Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support sql alchemy code generation #8

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
ae2f15a
base pydantic code generator
chicco785 Jul 28, 2023
80e89a7
fix __init__.py import
chicco785 Jul 29, 2023
d4c7333
Automated Black fmt fixes
Jul 29, 2023
39f7097
docs(release_notes): update RELEASE_NOTES.md
chicco785 Jul 29, 2023
b7d40ec
support cyclic reference serialization
chicco785 Jul 31, 2023
55cffd9
add pydantic to tests
chicco785 Jul 31, 2023
b9ab59e
Automated Black fmt fixes
Jul 31, 2023
a758990
docs(release_notes): update RELEASE_NOTES.md
chicco785 Jul 31, 2023
21ef5f2
fix import issue
chicco785 Jul 31, 2023
041662e
improve datatype support
chicco785 Jul 31, 2023
e2f6d5b
fix multiplicity support in validator generation
chicco785 Jul 31, 2023
ced74a0
add schema and pydantic to docker build
chicco785 Jul 31, 2023
e3d16fb
Automated Black fmt fixes
Jul 31, 2023
5622e45
fix Enum for CgmesProfile
chicco785 Jul 31, 2023
b25bc71
generates only EQ profile (tested in CIM-Manager)
chicco785 Aug 2, 2023
d62c17d
fix rendering for usage of &quote; in CMGES3.0
chicco785 Aug 2, 2023
fe2eb99
fix copy file path
chicco785 Aug 2, 2023
5b981ed
docs(release_notes): update RELEASE_NOTES.md
chicco785 Aug 2, 2023
f70f61f
Automated Black fmt fixes
Aug 2, 2023
afc1343
add support for GL profile
chicco785 Aug 2, 2023
4b6df40
fix model for PositionPoint
chicco785 Aug 2, 2023
4de83a9
fix model for PositionPoint
chicco785 Aug 2, 2023
1c00072
Update langPack.py
chicco785 Aug 2, 2023
2f17918
Automated Black fmt fixes
Aug 2, 2023
7926e3a
improve multiplicity handling
chicco785 Aug 2, 2023
14b5b7e
fix representation configuration for point
chicco785 Aug 2, 2023
7c82f18
Automated Black fmt fixes
Aug 2, 2023
0463300
use string as mrid while default value is uuid (serialized as a string)
chicco785 Aug 3, 2023
a4dd682
revert change
chicco785 Aug 3, 2023
e3e9c0c
Automated Black fmt fixes
Aug 3, 2023
5e09c9b
docs(release_notes): update RELEASE_NOTES.md
chicco785 Aug 3, 2023
b55b2d3
support defaults
chicco785 Aug 3, 2023
fea98ef
working on relationships
chicco785 Aug 7, 2023
7671a45
add back foreign keys in attribute relationships
chicco785 Aug 7, 2023
cba56e9
remote_side + foreign_keys
chicco785 Aug 7, 2023
0d84a76
compute db relationship type
chicco785 Aug 7, 2023
404bf69
one to many and many to one correctly supported
chicco785 Aug 7, 2023
741b87f
support correctly one-to-one relationship
chicco785 Aug 7, 2023
e7bf861
support many-to-many
chicco785 Aug 8, 2023
49051b0
generate gl
chicco785 Aug 8, 2023
63b061c
support usage of both defined and alias name to populate fields
chicco785 Aug 9, 2023
fee11ad
add test for sqlalchemy + add sqlalchemy folder to the docker build
chicco785 Aug 9, 2023
e6aa86c
Automated Black fmt fixes
Aug 9, 2023
2ac48a8
docs(release_notes): update RELEASE_NOTES.md
chicco785 Aug 9, 2023
5eef2e3
docs(release_notes): update RELEASE_NOTES.md
chicco785 Sep 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
- cpp
- java
- javascript
- pydantic
- sqlalchemy

steps:
- uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ cimpy/*
*.py[cod]
__pycache__/
.vscode/launch.json
CGMES_2.4.15_27JAN2020_pydantic/
88 changes: 87 additions & 1 deletion CIMgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ def __init__(self, rdfsEntry):
self.origin_list = []
self.super = rdfsEntry.subClassOf()
self.subclasses = []
self.root = rdfsEntry.subClassOf()

def attributes(self):
return self.attribute_list
Expand Down Expand Up @@ -255,6 +256,12 @@ def addOrigin(self, origin):
def superClass(self):
return self.super

def rootClass(self):
return self.root

def setRootClass(self, root):
self.root = root

def addSubClass(self, name):
self.subclasses.append(name)

Expand Down Expand Up @@ -490,6 +497,7 @@ def _write_python_files(elem_dict, langPack, outputPath, version):
"langPack": langPack,
"sub_class_of": elem_dict[class_name].superClass(),
"sub_classes": elem_dict[class_name].subClasses(),
"root": elem_dict[class_name].rootClass(),
}

# extract comments
Expand Down Expand Up @@ -687,6 +695,62 @@ def addSubClassesOfSubClasses(class_dict):
)


def addSubClassesOfSubClassesClean(class_dict, source):
temp = {}
for className in class_dict:
for name in class_dict[className].subClasses():
if name not in class_dict:
temp[name] = source[name]
addSubClassesOfSubClassesClean(temp, source)
class_dict.update(temp)


def addRootClassOfClean(class_dict):
temp = {}
for className in class_dict:
if class_dict[className].super:
temp[className] = class_dict[className]
temp[className].setRootClass(
findRootClass(class_dict[className].super, class_dict)
)
class_dict.update(temp)


def findRootClass(superClassName, class_dict):
for className in class_dict:
if className == superClassName:
if class_dict[className].super:
return findRootClass(class_dict[className].super, class_dict)
else:
return className
return None


def addInverseMultiplicity(class_dict):
temp = {}
for className in class_dict:
temp[className] = class_dict[className]
to_update = False
for attribute in _find_multiple_attributes(temp[className].attributes()):
if "inverseRole" in attribute:
to_update = True
attribute["inverseMultiplicity"] = findInverseMultiplicity(
attribute["inverseRole"], class_dict
)
if not to_update:
del temp[className]
class_dict.update(temp)


def findInverseMultiplicity(inverseRole, class_dict):
className = inverseRole.split(".")[0]
attributeLabel = inverseRole.split(".")[1]
for attribute in _find_multiple_attributes(class_dict[className].attributes()):
if attribute["label"] == attributeLabel:
return attribute["multiplicity"]
return None


def cim_generate(directory, outputPath, version, langPack):
"""Generates cgmes python classes from cgmes ontology

Expand Down Expand Up @@ -729,6 +793,8 @@ def cim_generate(directory, outputPath, version, langPack):
# merge classes from different profiles into one class and track origin of the classes and their attributes
class_dict_with_origins = _merge_classes(profiles_dict)

clean_class_dict = {}

# work out the subclasses for each class by noting the reverse relationship
for className in class_dict_with_origins:
superClassName = class_dict_with_origins[className].superClass()
Expand All @@ -742,7 +808,27 @@ def cim_generate(directory, outputPath, version, langPack):
# recursively add the subclasses of subclasses
addSubClassesOfSubClasses(class_dict_with_origins)

for className in class_dict_with_origins:
superClassName = class_dict_with_origins[className].superClass()
if (
superClassName == None
and class_dict_with_origins[className].has_instances()
):
clean_class_dict[className] = class_dict_with_origins[className]

for className in class_dict_with_origins:
superClassName = class_dict_with_origins[className].superClass()
if (
superClassName == None
and not class_dict_with_origins[className].has_instances()
):
clean_class_dict[className] = class_dict_with_origins[className]

addSubClassesOfSubClassesClean(clean_class_dict, class_dict_with_origins)
addRootClassOfClean(clean_class_dict)
addInverseMultiplicity(clean_class_dict)

# get information for writing python files and write python files
_write_python_files(class_dict_with_origins, langPack, outputPath, version)
_write_python_files(clean_class_dict, langPack, outputPath, version)

logger.info("Elapsed Time: {}s\n\n".format(time() - t0))
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ COPY cpp/ /CIMgen/cpp/
COPY java/ /CIMgen/java/
COPY javascript/ /CIMgen/javascript/
COPY python/ /CIMgen/python/
COPY pydantic/ /CIMgen/pydantic/
COPY sqlalchemy/ /CIMgen/sqlalchemy/
COPY CIMgen.py build.py /CIMgen/
COPY cgmes_schema/ /cgmes_schema
WORKDIR /CIMgen
ENTRYPOINT [ "/usr/bin/python3", "build.py", "--outdir=/cgmes_output", "--schemadir=/cgmes_schema" ]
CMD [ "--langdir=cpp" ]
6 changes: 5 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# cimgen Release Notes

## 0.0.1-dev - 2023-07-28
## 0.0.1-dev - 2023-09-13

### Features

- Support sql alchemy code generation (PR #8 by @chicco785)

### Continuous Integration

Expand Down
22 changes: 22 additions & 0 deletions pydantic/Base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from pydantic import BaseModel, ConfigDict


class Base(BaseModel):
model_config = ConfigDict(populate_by_name=True, defer_build=True)
"""
Base Class for CIM
"""

"""
not valid for pydantic 2.0
class Config:
@staticmethod
def schema_extra(schema: dict, _):
props = {}
for k, v in schema.get("properties", {}).items():
if not v.get("hidden", False):
props[k] = v
schema["properties"] = props """

def printxml(self, dict={}):
return dict
1 change: 1 addition & 0 deletions pydantic/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import pydantic.langPack
13 changes: 13 additions & 0 deletions pydantic/enum_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from enum import Enum, IntEnum


class CgmesProfileEnum(IntEnum):
EQ = 0
SSH = 1
TP = 2
SV = 3
DY = 4
GL = 5
DL = 5
TP_BD = 7
EQ_BD = 8
Loading