cognite-neat 0.121.1__py3-none-any.whl → 0.121.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/_version.py +1 -1
- cognite/neat/core/_client/_api/statistics.py +91 -0
- cognite/neat/core/_client/_api_client.py +2 -0
- cognite/neat/core/_client/data_classes/statistics.py +125 -0
- cognite/neat/core/_client/testing.py +4 -0
- cognite/neat/core/_constants.py +6 -7
- cognite/neat/core/_data_model/_constants.py +23 -16
- cognite/neat/core/_data_model/_shared.py +33 -17
- cognite/neat/core/_data_model/analysis/__init__.py +2 -2
- cognite/neat/core/_data_model/analysis/_base.py +186 -183
- cognite/neat/core/_data_model/catalog/__init__.py +1 -1
- cognite/neat/core/_data_model/exporters/__init__.py +5 -5
- cognite/neat/core/_data_model/exporters/_base.py +10 -8
- cognite/neat/core/_data_model/exporters/{_rules2dms.py → _data_model2dms.py} +22 -18
- cognite/neat/core/_data_model/exporters/{_rules2excel.py → _data_model2excel.py} +51 -51
- cognite/neat/core/_data_model/exporters/{_rules2instance_template.py → _data_model2instance_template.py} +4 -4
- cognite/neat/core/_data_model/exporters/{_rules2ontology.py → _data_model2ontology.py} +50 -50
- cognite/neat/core/_data_model/exporters/{_rules2yaml.py → _data_model2yaml.py} +21 -18
- cognite/neat/core/_data_model/importers/__init__.py +6 -6
- cognite/neat/core/_data_model/importers/_base.py +8 -6
- cognite/neat/core/_data_model/importers/_base_file_reader.py +56 -0
- cognite/neat/core/_data_model/importers/{_yaml2rules.py → _dict2data_model.py} +40 -20
- cognite/neat/core/_data_model/importers/{_dms2rules.py → _dms2data_model.py} +58 -49
- cognite/neat/core/_data_model/importers/{_dtdl2rules → _dtdl2data_model}/dtdl_converter.py +22 -22
- cognite/neat/core/_data_model/importers/{_dtdl2rules → _dtdl2data_model}/dtdl_importer.py +7 -7
- cognite/neat/core/_data_model/importers/{_dtdl2rules → _dtdl2data_model}/spec.py +3 -3
- cognite/neat/core/_data_model/importers/_rdf/_base.py +9 -9
- cognite/neat/core/_data_model/importers/_rdf/_imf2rules.py +15 -15
- cognite/neat/core/_data_model/importers/_rdf/_inference2rules.py +36 -36
- cognite/neat/core/_data_model/importers/_rdf/_owl2rules.py +12 -12
- cognite/neat/core/_data_model/importers/_rdf/_shared.py +25 -25
- cognite/neat/core/_data_model/importers/{_spreadsheet2rules.py → _spreadsheet2data_model.py} +72 -12
- cognite/neat/core/_data_model/models/__init__.py +8 -8
- cognite/neat/core/_data_model/models/_base_unverified.py +1 -1
- cognite/neat/core/_data_model/models/_base_verified.py +3 -3
- cognite/neat/core/_data_model/models/_types.py +6 -6
- cognite/neat/core/_data_model/models/conceptual/__init__.py +6 -6
- cognite/neat/core/_data_model/models/conceptual/_unverified.py +20 -20
- cognite/neat/core/_data_model/models/conceptual/_validation.py +87 -77
- cognite/neat/core/_data_model/models/conceptual/_verified.py +53 -51
- cognite/neat/core/_data_model/models/data_types.py +2 -2
- cognite/neat/core/_data_model/models/entities/__init__.py +8 -8
- cognite/neat/core/_data_model/models/entities/_loaders.py +11 -10
- cognite/neat/core/_data_model/models/entities/_multi_value.py +5 -5
- cognite/neat/core/_data_model/models/entities/_single_value.py +44 -38
- cognite/neat/core/_data_model/models/entities/_types.py +9 -3
- cognite/neat/core/_data_model/models/entities/_wrapped.py +3 -3
- cognite/neat/core/_data_model/models/mapping/_classic2core.py +12 -9
- cognite/neat/core/_data_model/models/physical/__init__.py +40 -0
- cognite/neat/core/_data_model/models/{dms → physical}/_exporter.py +71 -52
- cognite/neat/core/_data_model/models/{dms/_rules_input.py → physical/_unverified.py} +48 -39
- cognite/neat/core/_data_model/models/{dms → physical}/_validation.py +13 -11
- cognite/neat/core/_data_model/models/{dms/_rules.py → physical/_verified.py} +68 -60
- cognite/neat/core/_data_model/transformers/__init__.py +27 -23
- cognite/neat/core/_data_model/transformers/_base.py +26 -19
- cognite/neat/core/_data_model/transformers/_converters.py +703 -618
- cognite/neat/core/_data_model/transformers/_mapping.py +74 -55
- cognite/neat/core/_data_model/transformers/_verification.py +63 -54
- cognite/neat/core/_instances/extractors/_base.py +1 -1
- cognite/neat/core/_instances/extractors/_classic_cdf/_classic.py +8 -8
- cognite/neat/core/_instances/extractors/_dms_graph.py +42 -34
- cognite/neat/core/_instances/extractors/_mock_graph_generator.py +98 -95
- cognite/neat/core/_instances/loaders/_base.py +2 -2
- cognite/neat/core/_instances/loaders/_rdf2dms.py +6 -6
- cognite/neat/core/_instances/transformers/_base.py +7 -4
- cognite/neat/core/_instances/transformers/_value_type.py +2 -6
- cognite/neat/core/_issues/_base.py +4 -4
- cognite/neat/core/_issues/errors/__init__.py +2 -2
- cognite/neat/core/_issues/errors/_wrapper.py +2 -2
- cognite/neat/core/_issues/warnings/_models.py +4 -4
- cognite/neat/core/_store/__init__.py +3 -3
- cognite/neat/core/_store/{_rules_store.py → _data_model.py} +119 -112
- cognite/neat/core/_store/{_graph_store.py → _instance.py} +3 -4
- cognite/neat/core/_store/_provenance.py +2 -2
- cognite/neat/core/_store/exceptions.py +2 -2
- cognite/neat/core/_utils/rdf_.py +14 -0
- cognite/neat/core/_utils/text.py +1 -1
- cognite/neat/session/_base.py +22 -20
- cognite/neat/session/_drop.py +2 -2
- cognite/neat/session/_inspect.py +5 -5
- cognite/neat/session/_mapping.py +8 -6
- cognite/neat/session/_read.py +2 -2
- cognite/neat/session/_set.py +3 -3
- cognite/neat/session/_show.py +11 -11
- cognite/neat/session/_state.py +13 -13
- cognite/neat/session/_subset.py +12 -9
- cognite/neat/session/_template.py +13 -13
- cognite/neat/session/_to.py +17 -17
- {cognite_neat-0.121.1.dist-info → cognite_neat-0.121.2.dist-info}/METADATA +1 -1
- {cognite_neat-0.121.1.dist-info → cognite_neat-0.121.2.dist-info}/RECORD +95 -93
- cognite/neat/core/_data_model/exporters/_validation.py +0 -14
- cognite/neat/core/_data_model/models/dms/__init__.py +0 -32
- /cognite/neat/core/_data_model/catalog/{info-rules-imf.xlsx → conceptual-imf-data-model.xlsx} +0 -0
- /cognite/neat/core/_data_model/importers/{_dtdl2rules → _dtdl2data_model}/__init__.py +0 -0
- /cognite/neat/core/_data_model/importers/{_dtdl2rules → _dtdl2data_model}/_unit_lookup.py +0 -0
- {cognite_neat-0.121.1.dist-info → cognite_neat-0.121.2.dist-info}/WHEEL +0 -0
- {cognite_neat-0.121.1.dist-info → cognite_neat-0.121.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
_CATALOG = Path(__file__).parent
|
|
6
|
-
imf_attributes = _CATALOG / "
|
|
6
|
+
imf_attributes = _CATALOG / "conceptual-imf-data-model.xlsx"
|
|
7
7
|
hello_world_pump = _CATALOG / "hello_world_pump.xlsx"
|
|
8
8
|
classic_model = _CATALOG / "classic_model.xlsx"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from ._base import BaseExporter, CDFExporter
|
|
2
|
-
from .
|
|
3
|
-
from .
|
|
4
|
-
from .
|
|
5
|
-
from .
|
|
6
|
-
from .
|
|
2
|
+
from ._data_model2dms import DMSExporter
|
|
3
|
+
from ._data_model2excel import ExcelExporter
|
|
4
|
+
from ._data_model2instance_template import InstanceTemplateExporter
|
|
5
|
+
from ._data_model2ontology import GraphExporter, OWLExporter, SemanticDataModelExporter, SHACLExporter
|
|
6
|
+
from ._data_model2yaml import YAMLExporter
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
"BaseExporter",
|
|
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Generic, TypeVar, Union, get_args, get_origin
|
|
|
7
7
|
|
|
8
8
|
from cognite.neat.core._client import NeatClient
|
|
9
9
|
from cognite.neat.core._constants import DEFAULT_NAMESPACE
|
|
10
|
-
from cognite.neat.core._data_model._shared import
|
|
10
|
+
from cognite.neat.core._data_model._shared import T_VerifiedDataModel
|
|
11
11
|
from cognite.neat.core._utils.auxiliary import class_html_doc
|
|
12
12
|
from cognite.neat.core._utils.upload import UploadResult, UploadResultList
|
|
13
13
|
|
|
@@ -17,16 +17,16 @@ if TYPE_CHECKING:
|
|
|
17
17
|
T_Export = TypeVar("T_Export")
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class BaseExporter(ABC, Generic[
|
|
20
|
+
class BaseExporter(ABC, Generic[T_VerifiedDataModel, T_Export]):
|
|
21
21
|
_new_line = "\n"
|
|
22
22
|
_encoding = "utf-8"
|
|
23
23
|
|
|
24
24
|
@abstractmethod
|
|
25
|
-
def export_to_file(self,
|
|
25
|
+
def export_to_file(self, data_model: T_VerifiedDataModel, filepath: Path) -> None:
|
|
26
26
|
raise NotImplementedError
|
|
27
27
|
|
|
28
28
|
@abstractmethod
|
|
29
|
-
def export(self,
|
|
29
|
+
def export(self, data_model: T_VerifiedDataModel) -> T_Export:
|
|
30
30
|
raise NotImplementedError
|
|
31
31
|
|
|
32
32
|
@classmethod
|
|
@@ -54,12 +54,14 @@ class BaseExporter(ABC, Generic[T_VerifiedRules, T_Export]):
|
|
|
54
54
|
return (source_type,)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class CDFExporter(BaseExporter[
|
|
57
|
+
class CDFExporter(BaseExporter[T_VerifiedDataModel, T_Export], ABC):
|
|
58
58
|
@abstractmethod
|
|
59
59
|
def export_to_cdf_iterable(
|
|
60
|
-
self,
|
|
60
|
+
self, data_model: T_VerifiedDataModel, client: NeatClient, dry_run: bool = False
|
|
61
61
|
) -> Iterable[UploadResult]:
|
|
62
62
|
raise NotImplementedError
|
|
63
63
|
|
|
64
|
-
def export_to_cdf(
|
|
65
|
-
|
|
64
|
+
def export_to_cdf(
|
|
65
|
+
self, data_model: T_VerifiedDataModel, client: NeatClient, dry_run: bool = False
|
|
66
|
+
) -> UploadResultList:
|
|
67
|
+
return UploadResultList(self.export_to_cdf_iterable(data_model, client, dry_run))
|
|
@@ -28,7 +28,7 @@ from cognite.neat.core._client.data_classes.data_modeling import (
|
|
|
28
28
|
ViewApplyDict,
|
|
29
29
|
)
|
|
30
30
|
from cognite.neat.core._client.data_classes.schema import DMSSchema
|
|
31
|
-
from cognite.neat.core._data_model.models.
|
|
31
|
+
from cognite.neat.core._data_model.models.physical import PhysicalDataModel
|
|
32
32
|
from cognite.neat.core._issues import IssueList
|
|
33
33
|
from cognite.neat.core._issues.warnings import (
|
|
34
34
|
PrincipleOneModelOneSpaceWarning,
|
|
@@ -74,8 +74,8 @@ class ItemCategorized(Generic[T_ID, T_WriteClass]):
|
|
|
74
74
|
yield from (self.as_id(item) for item in self.to_create + self.to_update + self.to_delete + self.unchanged)
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
class DMSExporter(CDFExporter[
|
|
78
|
-
"""Export
|
|
77
|
+
class DMSExporter(CDFExporter[PhysicalDataModel, DMSSchema]):
|
|
78
|
+
"""Export data model to Cognite Data Fusion's Data Model Storage (DMS) service.
|
|
79
79
|
|
|
80
80
|
Args:
|
|
81
81
|
export_components (frozenset[Literal["all", "spaces", "data_models", "views", "containers"]], optional):
|
|
@@ -120,31 +120,31 @@ class DMSExporter(CDFExporter[DMSRules, DMSSchema]):
|
|
|
120
120
|
def description(self) -> str:
|
|
121
121
|
return "Export verified DMS Model to CDF."
|
|
122
122
|
|
|
123
|
-
def export_to_file(self,
|
|
124
|
-
"""Export the
|
|
123
|
+
def export_to_file(self, data_model: PhysicalDataModel, filepath: Path) -> None:
|
|
124
|
+
"""Export the data_model to a file(s).
|
|
125
125
|
|
|
126
126
|
If the file is a directory, the components will be exported to separate files, otherwise they will be
|
|
127
127
|
exported to a zip file.
|
|
128
128
|
|
|
129
129
|
Args:
|
|
130
130
|
filepath: Directory or zip file path to export to.
|
|
131
|
-
|
|
131
|
+
data_model:
|
|
132
132
|
"""
|
|
133
133
|
if filepath.is_dir():
|
|
134
|
-
self._export_to_directory(filepath,
|
|
134
|
+
self._export_to_directory(filepath, data_model)
|
|
135
135
|
else:
|
|
136
|
-
self._export_to_zip_file(filepath,
|
|
136
|
+
self._export_to_zip_file(filepath, data_model)
|
|
137
137
|
|
|
138
|
-
def _export_to_directory(self, directory: Path,
|
|
139
|
-
schema = self.export(
|
|
138
|
+
def _export_to_directory(self, directory: Path, data_model: PhysicalDataModel) -> None:
|
|
139
|
+
schema = self.export(data_model)
|
|
140
140
|
exclude = self._create_exclude_set()
|
|
141
141
|
schema.to_directory(directory, exclude=exclude, new_line=self._new_line, encoding=self._encoding)
|
|
142
142
|
|
|
143
|
-
def _export_to_zip_file(self, filepath: Path,
|
|
143
|
+
def _export_to_zip_file(self, filepath: Path, data_model: PhysicalDataModel) -> None:
|
|
144
144
|
if filepath.suffix not in {".zip"}:
|
|
145
145
|
warnings.warn("File extension is not .zip, adding it to the file name", stacklevel=2)
|
|
146
146
|
filepath = filepath.with_suffix(".zip")
|
|
147
|
-
schema = self.export(
|
|
147
|
+
schema = self.export(data_model)
|
|
148
148
|
exclude = self._create_exclude_set()
|
|
149
149
|
schema.to_zip(filepath, exclude=exclude)
|
|
150
150
|
|
|
@@ -155,14 +155,18 @@ class DMSExporter(CDFExporter[DMSRules, DMSSchema]):
|
|
|
155
155
|
exclude = {"spaces", "data_models", "views", "containers", "node_types"} - set(self.export_components)
|
|
156
156
|
return exclude
|
|
157
157
|
|
|
158
|
-
def export(self,
|
|
158
|
+
def export(self, data_model: PhysicalDataModel) -> DMSSchema:
|
|
159
159
|
# We do not want to include CogniteCore/CogniteProcess Industries in the schema
|
|
160
|
-
return
|
|
160
|
+
return data_model.as_schema(instance_space=self.instance_space, remove_cdf_spaces=self.remove_cdf_spaces)
|
|
161
161
|
|
|
162
162
|
def delete_from_cdf(
|
|
163
|
-
self,
|
|
163
|
+
self,
|
|
164
|
+
data_model: PhysicalDataModel,
|
|
165
|
+
client: NeatClient,
|
|
166
|
+
dry_run: bool = False,
|
|
167
|
+
skip_space: bool = False,
|
|
164
168
|
) -> Iterable[UploadResult]:
|
|
165
|
-
schema = self.export(
|
|
169
|
+
schema = self.export(data_model)
|
|
166
170
|
|
|
167
171
|
# we need to reverse order in which we are picking up the items to delete
|
|
168
172
|
# as they are sorted in the order of creation and we need to delete them in reverse order
|
|
@@ -202,9 +206,9 @@ class DMSExporter(CDFExporter[DMSRules, DMSSchema]):
|
|
|
202
206
|
yield result
|
|
203
207
|
|
|
204
208
|
def export_to_cdf_iterable(
|
|
205
|
-
self,
|
|
209
|
+
self, data_model: PhysicalDataModel, client: NeatClient, dry_run: bool = False
|
|
206
210
|
) -> Iterable[UploadResult]:
|
|
207
|
-
schema = self.export(
|
|
211
|
+
schema = self.export(data_model)
|
|
208
212
|
|
|
209
213
|
# The CDF UI does not deal well with a child view overwriting a parent property with the same name
|
|
210
214
|
# This is a workaround to remove the duplicated properties
|
|
@@ -16,7 +16,7 @@ from rdflib import Namespace
|
|
|
16
16
|
|
|
17
17
|
from cognite.neat.core._constants import BASE_MODEL, get_base_concepts
|
|
18
18
|
from cognite.neat.core._data_model._constants import get_internal_properties
|
|
19
|
-
from cognite.neat.core._data_model._shared import
|
|
19
|
+
from cognite.neat.core._data_model._shared import VerifiedDataModel
|
|
20
20
|
from cognite.neat.core._data_model.models import (
|
|
21
21
|
SheetRow,
|
|
22
22
|
)
|
|
@@ -30,7 +30,7 @@ from cognite.neat.core._data_model.models.conceptual._verified import (
|
|
|
30
30
|
from cognite.neat.core._data_model.models.data_types import (
|
|
31
31
|
_DATA_TYPE_BY_DMS_TYPE,
|
|
32
32
|
)
|
|
33
|
-
from cognite.neat.core._data_model.models.
|
|
33
|
+
from cognite.neat.core._data_model.models.physical._verified import PhysicalDataModel
|
|
34
34
|
from cognite.neat.core._utils.spreadsheet import (
|
|
35
35
|
find_column_with_value,
|
|
36
36
|
generate_data_validation,
|
|
@@ -41,16 +41,16 @@ from ._base import BaseExporter
|
|
|
41
41
|
MAX_COLUMN_WIDTH = 70.0
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
class ExcelExporter(BaseExporter[
|
|
45
|
-
"""Export
|
|
44
|
+
class ExcelExporter(BaseExporter[VerifiedDataModel, Workbook]):
|
|
45
|
+
"""Export data_model to Excel.
|
|
46
46
|
|
|
47
47
|
Args:
|
|
48
48
|
styling: The styling to use for the Excel file. Defaults to "default". See below for details
|
|
49
49
|
on the different styles.
|
|
50
50
|
new_model_id: The new model ID to use for the exported spreadsheet. This is only applicable if the input
|
|
51
|
-
|
|
51
|
+
data_model have 'is_reference' set. If provided, the model ID will be used to automatically create the
|
|
52
52
|
new metadata sheet in the Excel file. The model id is expected to be a tuple of (prefix, title)
|
|
53
|
-
(space, external_id) for
|
|
53
|
+
(space, external_id) for Conceptual and Physical Data Model respectively.
|
|
54
54
|
|
|
55
55
|
sheet_prefix: The prefix to use for the sheet names in the Excel file. Defaults to an empty string.
|
|
56
56
|
|
|
@@ -68,14 +68,14 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
68
68
|
_helper_sheet_name: str = "_helper"
|
|
69
69
|
_main_header_by_sheet_name: ClassVar[dict[str, str]] = {
|
|
70
70
|
"Properties": "Definition of Properties",
|
|
71
|
-
"
|
|
71
|
+
"Concepts": "Definition of Concepts",
|
|
72
72
|
"Views": "Definition of Views",
|
|
73
73
|
"Containers": "Definition of Containers",
|
|
74
74
|
"Nodes": "Definition of Nodes",
|
|
75
75
|
"Enum": "Definition of Enum Collections",
|
|
76
76
|
}
|
|
77
77
|
_helper_sheet_column_indexes_by_names: ClassVar[dict[str, int]] = {
|
|
78
|
-
"
|
|
78
|
+
"Concept": 1,
|
|
79
79
|
"View": 1,
|
|
80
80
|
"Implements": 2,
|
|
81
81
|
"Value Type": 3,
|
|
@@ -92,7 +92,7 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
92
92
|
styling: Style = "default",
|
|
93
93
|
new_model_id: tuple[str, str] | None = None,
|
|
94
94
|
sheet_prefix: str | None = None,
|
|
95
|
-
|
|
95
|
+
reference_data_model_with_prefix: tuple[VerifiedDataModel, str] | None = None,
|
|
96
96
|
add_empty_rows: bool = False,
|
|
97
97
|
hide_internal_columns: bool = True,
|
|
98
98
|
include_properties: Literal["same-space", "all"] = "all",
|
|
@@ -106,7 +106,7 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
106
106
|
self.styling = styling
|
|
107
107
|
self._styling_level = self.style_options.index(styling)
|
|
108
108
|
self.new_model_id = new_model_id
|
|
109
|
-
self.
|
|
109
|
+
self.reference_data_model_with_prefix = reference_data_model_with_prefix
|
|
110
110
|
self.add_empty_rows = add_empty_rows
|
|
111
111
|
self.hide_internal_columns = hide_internal_columns
|
|
112
112
|
self.include_properties = include_properties
|
|
@@ -118,9 +118,9 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
118
118
|
def description(self) -> str:
|
|
119
119
|
return "Export verified model to Excel."
|
|
120
120
|
|
|
121
|
-
def export_to_file(self,
|
|
122
|
-
"""Exports transformation
|
|
123
|
-
data = self.export(
|
|
121
|
+
def export_to_file(self, data_model: VerifiedDataModel, filepath: Path) -> None:
|
|
122
|
+
"""Exports transformation data_model to excel file."""
|
|
123
|
+
data = self.export(data_model)
|
|
124
124
|
try:
|
|
125
125
|
data.save(filepath)
|
|
126
126
|
finally:
|
|
@@ -145,14 +145,14 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
145
145
|
# Remove default sheet named "Sheet"
|
|
146
146
|
workbook.remove(workbook["Sheet"])
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
data_model_model = PhysicalDataModel if role == RoleTypes.dms else ConceptualDataModel
|
|
149
149
|
|
|
150
|
-
headers_by_sheet =
|
|
150
|
+
headers_by_sheet = data_model_model.headers_by_sheet(by_alias=True)
|
|
151
151
|
headers_by_sheet.pop("Metadata")
|
|
152
152
|
|
|
153
153
|
self._write_metadata_sheet(
|
|
154
154
|
workbook,
|
|
155
|
-
cast(BaseVerifiedMetadata,
|
|
155
|
+
cast(BaseVerifiedMetadata, data_model_model.model_fields["metadata"].annotation).default().model_dump(),
|
|
156
156
|
)
|
|
157
157
|
|
|
158
158
|
for sheet_name, headers in headers_by_sheet.items():
|
|
@@ -175,23 +175,23 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
175
175
|
|
|
176
176
|
return workbook
|
|
177
177
|
|
|
178
|
-
def export(self,
|
|
178
|
+
def export(self, data_model: VerifiedDataModel) -> Workbook:
|
|
179
179
|
workbook = Workbook()
|
|
180
180
|
# Remove default sheet named "Sheet"
|
|
181
181
|
workbook.remove(workbook["Sheet"])
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
dumped_user_data_model: dict[str, Any] = data_model.dump(by_alias=True)
|
|
184
184
|
|
|
185
|
-
self._write_metadata_sheet(workbook,
|
|
186
|
-
self._write_sheets(workbook,
|
|
187
|
-
if self.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
self._write_sheets(workbook,
|
|
191
|
-
self._write_metadata_sheet(workbook,
|
|
185
|
+
self._write_metadata_sheet(workbook, dumped_user_data_model["Metadata"], sheet_prefix=self.sheet_prefix)
|
|
186
|
+
self._write_sheets(workbook, dumped_user_data_model, data_model, sheet_prefix=self.sheet_prefix)
|
|
187
|
+
if self.reference_data_model_with_prefix:
|
|
188
|
+
reference_data_model, prefix = self.reference_data_model_with_prefix
|
|
189
|
+
dumped_reference_data_model = reference_data_model.dump(entities_exclude_defaults=False, by_alias=True)
|
|
190
|
+
self._write_sheets(workbook, dumped_reference_data_model, reference_data_model, sheet_prefix=prefix)
|
|
191
|
+
self._write_metadata_sheet(workbook, dumped_reference_data_model["Metadata"], sheet_prefix=prefix)
|
|
192
192
|
|
|
193
|
-
if isinstance(
|
|
194
|
-
self._write_prefixes_sheet(workbook,
|
|
193
|
+
if isinstance(data_model, ConceptualDataModel) and data_model.prefixes:
|
|
194
|
+
self._write_prefixes_sheet(workbook, data_model.prefixes)
|
|
195
195
|
|
|
196
196
|
if self._styling_level > 0:
|
|
197
197
|
self._adjust_column_widths(workbook)
|
|
@@ -199,9 +199,9 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
199
199
|
if self.hide_internal_columns:
|
|
200
200
|
self._hide_internal_columns(workbook)
|
|
201
201
|
|
|
202
|
-
# Only add drop downs if the
|
|
202
|
+
# Only add drop downs if the data_model are Physical Data Model
|
|
203
203
|
if self.add_drop_downs:
|
|
204
|
-
self._add_drop_downs(
|
|
204
|
+
self._add_drop_downs(data_model.metadata.role, workbook)
|
|
205
205
|
|
|
206
206
|
return workbook
|
|
207
207
|
|
|
@@ -227,7 +227,7 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
227
227
|
workbook: Workbook,
|
|
228
228
|
) -> None:
|
|
229
229
|
"""Adds drop down menus to specific columns for fast and accurate data entry
|
|
230
|
-
for both
|
|
230
|
+
for both Conceptual and Physical Data Model.
|
|
231
231
|
|
|
232
232
|
Args:
|
|
233
233
|
role: The role for which the drop downs are created. Can be either "dms" or "information".
|
|
@@ -241,8 +241,8 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
241
241
|
|
|
242
242
|
!!! note "Why 100*100 rows?"
|
|
243
243
|
This is due to the fact that we need to add drop down menus for all properties
|
|
244
|
-
in the sheet. The maximum number of properties per view/
|
|
245
|
-
maximum number of views/
|
|
244
|
+
in the sheet. The maximum number of properties per view/concept is 100. So considering
|
|
245
|
+
maximum number of views/concepts is 100, we need to add 100*100 rows.
|
|
246
246
|
"""
|
|
247
247
|
|
|
248
248
|
self._make_helper_sheet(role, workbook, 100)
|
|
@@ -254,7 +254,7 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
254
254
|
|
|
255
255
|
self._add_data_validation(
|
|
256
256
|
workbook,
|
|
257
|
-
sheet_name="Views" if role == RoleTypes.dms else "
|
|
257
|
+
sheet_name="Views" if role == RoleTypes.dms else "Concepts",
|
|
258
258
|
column_name="Implements",
|
|
259
259
|
data_validator_name="implements",
|
|
260
260
|
data_validators=data_validators,
|
|
@@ -275,8 +275,8 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
275
275
|
self._add_data_validation(
|
|
276
276
|
workbook,
|
|
277
277
|
sheet_name="Properties",
|
|
278
|
-
column_name="View" if role == RoleTypes.dms else "
|
|
279
|
-
data_validator_name="
|
|
278
|
+
column_name="View" if role == RoleTypes.dms else "Concept",
|
|
279
|
+
data_validator_name="views_or_concepts",
|
|
280
280
|
data_validators=data_validators,
|
|
281
281
|
validation_range=100,
|
|
282
282
|
total_rows=100 * 100,
|
|
@@ -364,26 +364,26 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
364
364
|
)
|
|
365
365
|
concept_counter += 1
|
|
366
366
|
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
views_or_concepts_sheet = "Views" if role == RoleTypes.dms else "Concepts"
|
|
368
|
+
view_or_concept_column = "View" if role == RoleTypes.dms else "Concept"
|
|
369
369
|
|
|
370
370
|
for i in range(no_rows):
|
|
371
371
|
workbook[self._helper_sheet_name].cell(
|
|
372
372
|
row=i + 1,
|
|
373
|
-
column=self._helper_sheet_column_indexes_by_names[
|
|
374
|
-
value=f'=IF(ISBLANK({
|
|
373
|
+
column=self._helper_sheet_column_indexes_by_names[view_or_concept_column],
|
|
374
|
+
value=f'=IF(ISBLANK({views_or_concepts_sheet}!A{i + 3}), "", {views_or_concepts_sheet}!A{i + 3})',
|
|
375
375
|
)
|
|
376
376
|
|
|
377
377
|
workbook[self._helper_sheet_name].cell(
|
|
378
378
|
row=concept_counter + i + 1,
|
|
379
379
|
column=self._helper_sheet_column_indexes_by_names["Implements"],
|
|
380
|
-
value=f'=IF(ISBLANK({
|
|
380
|
+
value=f'=IF(ISBLANK({views_or_concepts_sheet}!A{i + 3}), "", {views_or_concepts_sheet}!A{i + 3})',
|
|
381
381
|
)
|
|
382
382
|
|
|
383
383
|
workbook[self._helper_sheet_name].cell(
|
|
384
384
|
row=value_type_counter + i + 1,
|
|
385
385
|
column=self._helper_sheet_column_indexes_by_names["Value Type"],
|
|
386
|
-
value=f'=IF(ISBLANK({
|
|
386
|
+
value=f'=IF(ISBLANK({views_or_concepts_sheet}!A{i + 3}), "", {views_or_concepts_sheet}!A{i + 3})',
|
|
387
387
|
)
|
|
388
388
|
|
|
389
389
|
if role == RoleTypes.dms:
|
|
@@ -507,11 +507,11 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
507
507
|
def _write_sheets(
|
|
508
508
|
self,
|
|
509
509
|
workbook: Workbook,
|
|
510
|
-
|
|
511
|
-
|
|
510
|
+
dumped_data_model: dict[str, Any],
|
|
511
|
+
data_model: VerifiedDataModel,
|
|
512
512
|
sheet_prefix: str = "",
|
|
513
513
|
) -> None:
|
|
514
|
-
for sheet_name, headers in
|
|
514
|
+
for sheet_name, headers in data_model.headers_by_sheet(by_alias=True).items():
|
|
515
515
|
if sheet_name in ("Metadata", "Prefixes", "Reference", "Last"):
|
|
516
516
|
continue
|
|
517
517
|
|
|
@@ -519,17 +519,17 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
519
519
|
|
|
520
520
|
fill_colors = itertools.cycle(["CADCFC", "FFFFFF"])
|
|
521
521
|
fill_color = next(fill_colors)
|
|
522
|
-
|
|
522
|
+
last_concept: str | None = None
|
|
523
523
|
item: dict[str, Any]
|
|
524
|
-
for item in
|
|
524
|
+
for item in dumped_data_model.get(sheet_name) or []:
|
|
525
525
|
if "Neat ID" in item:
|
|
526
526
|
# Move the Neat ID to the end of the columns
|
|
527
527
|
item["Neat ID"] = item.pop("Neat ID")
|
|
528
528
|
row = list(item.values())
|
|
529
|
-
|
|
529
|
+
concept = row[0]
|
|
530
530
|
|
|
531
531
|
is_properties = sheet_name == "Properties"
|
|
532
|
-
is_new_class =
|
|
532
|
+
is_new_class = concept != last_concept and last_concept is not None
|
|
533
533
|
if self._styling_level > 2 and is_new_class and is_properties:
|
|
534
534
|
if self.add_empty_rows:
|
|
535
535
|
sheet.append([""] * len(headers))
|
|
@@ -540,8 +540,8 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
540
540
|
fill_color = next(fill_colors)
|
|
541
541
|
|
|
542
542
|
if is_properties and self.include_properties == "same-space":
|
|
543
|
-
space =
|
|
544
|
-
if space !=
|
|
543
|
+
space = concept.split(":")[0] if ":" in concept else data_model.metadata.space
|
|
544
|
+
if space != data_model.metadata.space:
|
|
545
545
|
continue
|
|
546
546
|
|
|
547
547
|
sheet.append(row)
|
|
@@ -550,7 +550,7 @@ class ExcelExporter(BaseExporter[VerifiedRules, Workbook]):
|
|
|
550
550
|
cell.fill = PatternFill(fgColor=fill_color, patternType="solid")
|
|
551
551
|
side = Side(style="thin", color="000000")
|
|
552
552
|
cell.border = Border(left=side, right=side, top=side, bottom=side)
|
|
553
|
-
|
|
553
|
+
last_concept = concept
|
|
554
554
|
|
|
555
555
|
self._style_sheet_header(sheet, headers)
|
|
556
556
|
|
|
@@ -9,11 +9,11 @@ from openpyxl.utils import get_column_letter
|
|
|
9
9
|
from openpyxl.worksheet.datavalidation import DataValidation
|
|
10
10
|
|
|
11
11
|
from cognite.neat.core._data_model._constants import EntityTypes
|
|
12
|
-
from cognite.neat.core._data_model.analysis import
|
|
12
|
+
from cognite.neat.core._data_model.analysis import DataModelAnalysis
|
|
13
13
|
from cognite.neat.core._data_model.models.conceptual._verified import (
|
|
14
14
|
ConceptualDataModel,
|
|
15
15
|
)
|
|
16
|
-
from cognite.neat.core._data_model.models.entities._single_value import
|
|
16
|
+
from cognite.neat.core._data_model.models.entities._single_value import ConceptEntity
|
|
17
17
|
|
|
18
18
|
from ._base import BaseExporter
|
|
19
19
|
|
|
@@ -57,7 +57,7 @@ class InstanceTemplateExporter(BaseExporter[ConceptualDataModel, Workbook]):
|
|
|
57
57
|
# Remove default sheet named "Sheet"
|
|
58
58
|
workbook.remove(workbook["Sheet"])
|
|
59
59
|
|
|
60
|
-
for class_, properties in
|
|
60
|
+
for class_, properties in DataModelAnalysis(rules).properties_by_id_by_concept().items():
|
|
61
61
|
workbook.create_sheet(title=class_.suffix)
|
|
62
62
|
|
|
63
63
|
# Add header rows
|
|
@@ -76,7 +76,7 @@ class InstanceTemplateExporter(BaseExporter[ConceptualDataModel, Workbook]):
|
|
|
76
76
|
class_.suffix,
|
|
77
77
|
get_column_letter(i + 2),
|
|
78
78
|
self.no_rows,
|
|
79
|
-
cast(
|
|
79
|
+
cast(ConceptEntity, property_.value_type).suffix,
|
|
80
80
|
"A",
|
|
81
81
|
)
|
|
82
82
|
|