cognite-neat 0.75.9__tar.gz → 0.76.0__tar.gz
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-0.75.9 → cognite_neat-0.76.0}/PKG-INFO +1 -1
- cognite_neat-0.76.0/cognite/neat/_version.py +1 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_models.py +3 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2dms.py +46 -4
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2excel.py +0 -9
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_base.py +6 -0
- cognite_neat-0.76.0/cognite/neat/rules/importers/_dms2rules.py +410 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_spreadsheet2rules.py +14 -8
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/base.py +3 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/dms.py +142 -54
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/fileread.py +41 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/importing.py +155 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/spreadsheet.py +12 -9
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/entities.py +29 -6
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_base.py +5 -6
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_dms_architect_rules.py +492 -332
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_dms_rules_write.py +32 -30
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_dms_schema.py +112 -22
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_domain_rules.py +5 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_information_rules.py +13 -6
- cognite_neat-0.76.0/cognite/neat/rules/models/wrapped_entities.py +166 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/pyproject.toml +1 -1
- cognite_neat-0.75.9/cognite/neat/_version.py +0 -1
- cognite_neat-0.75.9/cognite/neat/rules/importers/_dms2rules.py +0 -216
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/LICENSE +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/README.md +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/asgi/metrics.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/configuration.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/context_manager/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/context_manager/manager.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/data_classes/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/data_classes/rest.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/explorer.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/configuration.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/core.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/crud.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/data_exploration.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/metrics.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/routers/workflows.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/data_mapping.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/logging.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/api/utils/query_templates.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/main.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/monitoring/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/monitoring/metrics.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/index.html +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/.gitignore +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/README.md +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/asset-manifest.json +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/favicon.ico +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/img/architect-icon.svg +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/img/developer-icon.svg +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/img/sme-icon.svg +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/index.html +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/logo192.png +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/manifest.json +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/robots.txt +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/css/main.38a62222.css.map +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.LICENSE.txt +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/js/main.ec7f72e2.js.map +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/app/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/config.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/constants.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/extractors/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/extractors/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/extractors/_mock_graph_generator.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/models.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_graphdb_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_memory_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_oxigraph_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_oxrdflib.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/graph/stores/_rdf_to_graph.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_dexpi.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_graph_capturing_sheet.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/extractors/_mock_graph_generator.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/_asset_loader.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/_exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/labels.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/models.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/rdf_to_assets.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/core/rdf_to_relationships.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/rdf_to_dms.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/loaders/validator.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/models.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_graphdb_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_memory_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_oxigraph_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_oxrdflib.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/stores/_rdf_to_graph.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/entity_matcher.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/query_generator/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/query_generator/sparql.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/graph/transformations/transformer.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/analysis.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/Rules-Nordic44-to-TNT.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/Rules-Nordic44-to-graphql.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/power-grid-containers.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/power-grid-example.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/power-grid-model.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/rules-template.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/sheet2cdf-transformation-rules.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/skos-rules.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/source-to-solution-mapping-rules.xlsx +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/examples/wind-energy.owl +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_core/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_core/rules2labels.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2dms.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2excel.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2graphql.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2ontology.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2pydantic_models.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_rules2triples.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/exporters/_validation.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_dict2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_dms2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_graph2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_json2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2classes.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2metadata.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2properties.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_owl2rules/_owl2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_spreadsheet2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_xsd2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/importers/_yaml2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/raw_rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/rdfpath.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/tables.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/rules/models/value_types.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Export_DMS/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Import_DMS/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Validate_Rules/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/legacy/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/py.typed +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/_shared.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/analysis/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/analysis/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/analysis/_information_rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/examples/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/examples/wind-energy.owl +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2ontology.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_rules2yaml.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/exporters/_validation.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_dtdl2rules/spec.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2classes.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2metadata.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2properties.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_owl2rules/_owl2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_yaml2rules.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/formatters.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/issues/spreadsheet_file.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/data_types.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rdfpath.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_types/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_types/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/models/rules/_types/_field.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/auxiliary.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/_base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/_data_modeling.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/_ingestion.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/cdf_loaders/data_classes.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/spreadsheet.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/text.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/utils.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/utils/xml.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/_exceptions.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/base.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/cdf_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Export_DMS/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Export_Rules_to_Ontology/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Extract_DEXPI_Graph_and_Export_Rules/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Extract_RDF_Graph_and_Generate_Assets/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Import_DMS/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Ontology_to_Data_Model/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Validate_Rules/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Validate_Solution_Model/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Visualize_Data_Model_Using_Mock_Graph/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/examples/Visualize_Semantic_Data_Model/workflow.yaml +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/manager.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/migration/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/migration/steps.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/migration/wf_manifests.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/model.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/data_contracts.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/graph_extractor.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/graph_loader.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/graph_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/rules_exporter.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/rules_importer.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/current/rules_validator.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/io/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/io/io_steps.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/__init__.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_contextualization.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_extractor.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_loader.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_store.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/graph_transformer.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/rules_exporter.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/lib/legacy/rules_importer.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps/step_model.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/steps_registry.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/tasks.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/triggers.py +0 -0
- {cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/workflows/utils.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.76.0"
|
|
@@ -2,6 +2,8 @@ from abc import ABC
|
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
3
|
from functools import total_ordering
|
|
4
4
|
|
|
5
|
+
from cognite.neat.rules.issues import IssueList
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
@total_ordering
|
|
7
9
|
@dataclass
|
|
@@ -32,6 +34,7 @@ class UploadResult(UploadResultCore):
|
|
|
32
34
|
failed_changed: int = 0
|
|
33
35
|
failed_deleted: int = 0
|
|
34
36
|
error_messages: list[str] = field(default_factory=list)
|
|
37
|
+
issues: IssueList = field(default_factory=IssueList)
|
|
35
38
|
|
|
36
39
|
@property
|
|
37
40
|
def total(self) -> int:
|
|
@@ -4,10 +4,13 @@ from pathlib import Path
|
|
|
4
4
|
from typing import Literal, TypeAlias, cast
|
|
5
5
|
|
|
6
6
|
from cognite.client import CogniteClient
|
|
7
|
-
from cognite.client.data_classes._base import CogniteResourceList
|
|
7
|
+
from cognite.client.data_classes._base import CogniteResource, CogniteResourceList
|
|
8
|
+
from cognite.client.data_classes.data_modeling import DataModelApply, DataModelId
|
|
8
9
|
from cognite.client.exceptions import CogniteAPIError
|
|
9
10
|
|
|
11
|
+
from cognite.neat.rules import issues
|
|
10
12
|
from cognite.neat.rules._shared import Rules
|
|
13
|
+
from cognite.neat.rules.issues import IssueList
|
|
11
14
|
from cognite.neat.rules.models.rules import InformationRules
|
|
12
15
|
from cognite.neat.rules.models.rules._base import ExtensionCategory, SheetList
|
|
13
16
|
from cognite.neat.rules.models.rules._dms_architect_rules import DMSContainer, DMSRules
|
|
@@ -43,6 +46,8 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
43
46
|
export_pipeline (bool, optional): Whether to export the pipeline. Defaults to False. This means setting
|
|
44
47
|
up transformations, RAW databases and tables to populate the data model.
|
|
45
48
|
instance_space (str, optional): The space to use for the instance. Defaults to None.
|
|
49
|
+
suppress_warnings (bool, optional): Suppress warnings. Defaults to False.
|
|
50
|
+
|
|
46
51
|
... note::
|
|
47
52
|
|
|
48
53
|
- "fail": If any component already exists, the export will fail.
|
|
@@ -59,12 +64,14 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
59
64
|
existing_handling: Literal["fail", "skip", "update", "force"] = "update",
|
|
60
65
|
export_pipeline: bool = False,
|
|
61
66
|
instance_space: str | None = None,
|
|
67
|
+
suppress_warnings: bool = False,
|
|
62
68
|
):
|
|
63
69
|
self.export_components = {export_components} if isinstance(export_components, str) else set(export_components)
|
|
64
70
|
self.include_space = include_space
|
|
65
71
|
self.existing_handling = existing_handling
|
|
66
72
|
self.export_pipeline = export_pipeline
|
|
67
73
|
self.instance_space = instance_space
|
|
74
|
+
self.suppress_warnings = suppress_warnings
|
|
68
75
|
self._schema: DMSSchema | None = None
|
|
69
76
|
|
|
70
77
|
def export_to_file(self, rules: Rules, filepath: Path) -> None:
|
|
@@ -115,11 +122,11 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
115
122
|
)
|
|
116
123
|
is_new_model = dms_rules.reference is None
|
|
117
124
|
if is_new_model or is_solution_model:
|
|
118
|
-
return dms_rules.as_schema(self.export_pipeline, self.instance_space)
|
|
125
|
+
return dms_rules.as_schema(False, self.export_pipeline, self.instance_space)
|
|
119
126
|
|
|
120
127
|
# This is an extension of an existing model.
|
|
121
128
|
reference_rules = cast(DMSRules, dms_rules.reference).model_copy(deep=True)
|
|
122
|
-
reference_schema = reference_rules.as_schema(self.export_pipeline)
|
|
129
|
+
reference_schema = reference_rules.as_schema(include_ref=False, include_pipeline=self.export_pipeline)
|
|
123
130
|
|
|
124
131
|
# Todo Move this to an appropriate location
|
|
125
132
|
# Merging Reference with User Rules
|
|
@@ -142,7 +149,7 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
142
149
|
property_.reference = None
|
|
143
150
|
combined_rules.properties.append(property_)
|
|
144
151
|
|
|
145
|
-
schema = combined_rules.as_schema(self.export_pipeline, self.instance_space)
|
|
152
|
+
schema = combined_rules.as_schema(True, self.export_pipeline, self.instance_space)
|
|
146
153
|
|
|
147
154
|
if dms_rules.metadata.extension in (ExtensionCategory.addition, ExtensionCategory.reshape):
|
|
148
155
|
# We do not freeze views as they might be changed, even for addition,
|
|
@@ -206,6 +213,7 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
206
213
|
redeploy_data_model = False
|
|
207
214
|
|
|
208
215
|
for all_items, loader in to_export:
|
|
216
|
+
issue_list = IssueList()
|
|
209
217
|
all_item_ids = loader.get_ids(all_items)
|
|
210
218
|
skipped = sum(1 for item_id in all_item_ids if item_id in schema.frozen_ids)
|
|
211
219
|
item_ids = [item_id for item_id in all_item_ids if item_id not in schema.frozen_ids]
|
|
@@ -249,6 +257,9 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
249
257
|
else:
|
|
250
258
|
raise ValueError(f"Unsupported existing_handling {self.existing_handling}")
|
|
251
259
|
|
|
260
|
+
warning_list = self._validate(loader, items)
|
|
261
|
+
issue_list.extend(warning_list)
|
|
262
|
+
|
|
252
263
|
error_messages: list[str] = []
|
|
253
264
|
if not dry_run:
|
|
254
265
|
if to_delete:
|
|
@@ -284,6 +295,7 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
284
295
|
failed_created=failed_created,
|
|
285
296
|
failed_changed=failed_changed,
|
|
286
297
|
error_messages=error_messages,
|
|
298
|
+
issues=issue_list,
|
|
287
299
|
)
|
|
288
300
|
|
|
289
301
|
if loader.resource_name == "views" and (created or changed) and not redeploy_data_model:
|
|
@@ -307,3 +319,33 @@ class DMSExporter(CDFExporter[DMSSchema]):
|
|
|
307
319
|
to_export.append((schema.raw_tables, RawTableLoader(client)))
|
|
308
320
|
to_export.append((schema.transformations, TransformationLoader(client)))
|
|
309
321
|
return schema, to_export
|
|
322
|
+
|
|
323
|
+
def _validate(self, loader: ResourceLoader, items: list[CogniteResource]) -> IssueList:
|
|
324
|
+
issue_list = IssueList()
|
|
325
|
+
if isinstance(loader, DataModelLoader):
|
|
326
|
+
models = cast(list[DataModelApply], items)
|
|
327
|
+
if other_models := self._exist_other_data_models(loader, models):
|
|
328
|
+
warning = issues.dms.OtherDataModelsInSpaceWarning(models[0].space, other_models)
|
|
329
|
+
if not self.suppress_warnings:
|
|
330
|
+
warnings.warn(warning, stacklevel=2)
|
|
331
|
+
issue_list.append(warning)
|
|
332
|
+
|
|
333
|
+
return issue_list
|
|
334
|
+
|
|
335
|
+
@classmethod
|
|
336
|
+
def _exist_other_data_models(cls, loader: DataModelLoader, models: list[DataModelApply]) -> list[DataModelId]:
|
|
337
|
+
if not models:
|
|
338
|
+
return []
|
|
339
|
+
space = models[0].space
|
|
340
|
+
external_id = models[0].external_id
|
|
341
|
+
try:
|
|
342
|
+
data_models = loader.client.data_modeling.data_models.list(space=space, limit=25, all_versions=False)
|
|
343
|
+
except CogniteAPIError as e:
|
|
344
|
+
warnings.warn(issues.importing.APIWarning(str(e)), stacklevel=2)
|
|
345
|
+
return []
|
|
346
|
+
else:
|
|
347
|
+
return [
|
|
348
|
+
data_model.as_id()
|
|
349
|
+
for data_model in data_models
|
|
350
|
+
if (data_model.space, data_model.external_id) != (space, external_id)
|
|
351
|
+
]
|
|
@@ -120,13 +120,6 @@ class ExcelExporter(BaseExporter[Workbook]):
|
|
|
120
120
|
else:
|
|
121
121
|
sheet = workbook.create_sheet(sheet_name)
|
|
122
122
|
|
|
123
|
-
# Reorder such that the first column is class + the first field of the subclass
|
|
124
|
-
# of sheet entity. This is to make the properties/classes/views/containers sheet more readable.
|
|
125
|
-
# For example, for the properties these that means class, property, name, description
|
|
126
|
-
# instead of class, name, description, property
|
|
127
|
-
move = len(SheetEntity.model_fields) - 1 # -1 is for the class field
|
|
128
|
-
headers = headers[:1] + headers[move : move + 1] + headers[1:move] + headers[move + 1 :]
|
|
129
|
-
|
|
130
123
|
main_header = self._main_header_by_sheet_name[sheet_name]
|
|
131
124
|
sheet.append([main_header] + [""] * (len(headers) - 1))
|
|
132
125
|
sheet.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(headers))
|
|
@@ -150,8 +143,6 @@ class ExcelExporter(BaseExporter[Workbook]):
|
|
|
150
143
|
cell.border = Border(left=side, right=side, top=side, bottom=side)
|
|
151
144
|
fill_color = next(fill_colors)
|
|
152
145
|
|
|
153
|
-
# Need to do the same reordering as for the headers above
|
|
154
|
-
row = row[:1] + row[move : move + 1] + row[1:move] + row[move + 1 :]
|
|
155
146
|
sheet.append(row)
|
|
156
147
|
if self._styling_level > 2 and is_properties:
|
|
157
148
|
for cell in sheet[sheet.max_row]:
|
|
@@ -60,6 +60,12 @@ class BaseImporter(ABC):
|
|
|
60
60
|
else:
|
|
61
61
|
return output, issues
|
|
62
62
|
|
|
63
|
+
@classmethod
|
|
64
|
+
def _return_or_raise(cls, issue_list: IssueList, errors: Literal["raise", "continue"]) -> tuple[None, IssueList]:
|
|
65
|
+
if errors == "raise":
|
|
66
|
+
raise issue_list.as_errors()
|
|
67
|
+
return None, issue_list
|
|
68
|
+
|
|
63
69
|
def _default_metadata(self):
|
|
64
70
|
return {
|
|
65
71
|
"prefix": "neat",
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
from collections import Counter
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Literal, cast, overload
|
|
6
|
+
|
|
7
|
+
from cognite.client import CogniteClient
|
|
8
|
+
from cognite.client import data_modeling as dm
|
|
9
|
+
from cognite.client.data_classes.data_modeling import DataModelIdentifier
|
|
10
|
+
from cognite.client.data_classes.data_modeling.containers import BTreeIndex, InvertedIndex
|
|
11
|
+
from cognite.client.data_classes.data_modeling.views import (
|
|
12
|
+
MultiEdgeConnectionApply,
|
|
13
|
+
MultiReverseDirectRelationApply,
|
|
14
|
+
SingleEdgeConnectionApply,
|
|
15
|
+
SingleReverseDirectRelationApply,
|
|
16
|
+
ViewPropertyApply,
|
|
17
|
+
)
|
|
18
|
+
from cognite.client.utils import ms_to_datetime
|
|
19
|
+
|
|
20
|
+
from cognite.neat.rules import issues
|
|
21
|
+
from cognite.neat.rules.importers._base import BaseImporter, Rules, _handle_issues
|
|
22
|
+
from cognite.neat.rules.issues import IssueList, ValidationIssue
|
|
23
|
+
from cognite.neat.rules.models.data_types import DataType
|
|
24
|
+
from cognite.neat.rules.models.entities import (
|
|
25
|
+
ClassEntity,
|
|
26
|
+
ContainerEntity,
|
|
27
|
+
DataModelEntity,
|
|
28
|
+
DMSUnknownEntity,
|
|
29
|
+
ViewEntity,
|
|
30
|
+
ViewPropertyEntity,
|
|
31
|
+
)
|
|
32
|
+
from cognite.neat.rules.models.rules import DMSRules, DMSSchema, RoleTypes
|
|
33
|
+
from cognite.neat.rules.models.rules._base import DataModelType, ExtensionCategory, SchemaCompleteness
|
|
34
|
+
from cognite.neat.rules.models.rules._dms_architect_rules import (
|
|
35
|
+
DMSContainer,
|
|
36
|
+
DMSMetadata,
|
|
37
|
+
DMSProperty,
|
|
38
|
+
DMSView,
|
|
39
|
+
SheetList,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class DMSImporter(BaseImporter):
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
schema: DMSSchema,
|
|
47
|
+
read_issues: Sequence[ValidationIssue] | None = None,
|
|
48
|
+
metadata: DMSMetadata | None = None,
|
|
49
|
+
):
|
|
50
|
+
self.schema = schema
|
|
51
|
+
self.metadata = metadata
|
|
52
|
+
self.issue_list = IssueList(read_issues)
|
|
53
|
+
self._container_by_id = {container.as_id(): container for container in schema.containers}
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def from_data_model_id(cls, client: CogniteClient, data_model_id: DataModelIdentifier) -> "DMSImporter":
|
|
57
|
+
"""Create a DMSImporter ready to convert the given data model to rules.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
client: Instantiated CogniteClient to retrieve data model.
|
|
61
|
+
data_model_id: Data Model to retrieve.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
DMSImporter: DMSImporter instance
|
|
65
|
+
"""
|
|
66
|
+
data_models = client.data_modeling.data_models.retrieve(data_model_id, inline_views=True)
|
|
67
|
+
if len(data_models) == 0:
|
|
68
|
+
return cls(DMSSchema(), [issues.importing.NoDataModelError(f"Data model {data_model_id} not found")])
|
|
69
|
+
data_model = data_models.latest_version()
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
schema = DMSSchema.from_data_model(client, data_model)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
return cls(DMSSchema(), [issues.importing.APIError(str(e))])
|
|
75
|
+
|
|
76
|
+
created = ms_to_datetime(data_model.created_time)
|
|
77
|
+
updated = ms_to_datetime(data_model.last_updated_time)
|
|
78
|
+
|
|
79
|
+
metadata = cls._create_metadata_from_model(data_model, created, updated)
|
|
80
|
+
|
|
81
|
+
return cls(schema, [], metadata)
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def _create_metadata_from_model(
|
|
85
|
+
cls,
|
|
86
|
+
model: dm.DataModel[dm.View] | dm.DataModelApply,
|
|
87
|
+
created: datetime | None = None,
|
|
88
|
+
updated: datetime | None = None,
|
|
89
|
+
) -> DMSMetadata:
|
|
90
|
+
description, creator = DMSMetadata._get_description_and_creator(model.description)
|
|
91
|
+
now = datetime.now().replace(microsecond=0)
|
|
92
|
+
return DMSMetadata(
|
|
93
|
+
schema_=SchemaCompleteness.complete,
|
|
94
|
+
extension=ExtensionCategory.addition,
|
|
95
|
+
space=model.space,
|
|
96
|
+
external_id=model.external_id,
|
|
97
|
+
name=model.name or model.external_id,
|
|
98
|
+
version=model.version or "0.1.0",
|
|
99
|
+
updated=updated or now,
|
|
100
|
+
created=created or now,
|
|
101
|
+
creator=creator,
|
|
102
|
+
description=description,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def from_directory(cls, directory: str | Path) -> "DMSImporter":
|
|
107
|
+
issue_list = IssueList()
|
|
108
|
+
with _handle_issues(issue_list) as _:
|
|
109
|
+
schema = DMSSchema.from_directory(directory)
|
|
110
|
+
# If there were errors during the import, the to_rules
|
|
111
|
+
return cls(schema, issue_list)
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def from_zip_file(cls, zip_file: str | Path) -> "DMSImporter":
|
|
115
|
+
if Path(zip_file).suffix != ".zip":
|
|
116
|
+
return cls(DMSSchema(), [issues.fileread.InvalidFileFormatError(Path(zip_file), [".zip"])])
|
|
117
|
+
issue_list = IssueList()
|
|
118
|
+
with _handle_issues(issue_list) as _:
|
|
119
|
+
schema = DMSSchema.from_zip(zip_file)
|
|
120
|
+
return cls(schema, issue_list)
|
|
121
|
+
|
|
122
|
+
@overload
|
|
123
|
+
def to_rules(self, errors: Literal["raise"], role: RoleTypes | None = None) -> Rules: ...
|
|
124
|
+
|
|
125
|
+
@overload
|
|
126
|
+
def to_rules(
|
|
127
|
+
self, errors: Literal["continue"] = "continue", role: RoleTypes | None = None
|
|
128
|
+
) -> tuple[Rules | None, IssueList]: ...
|
|
129
|
+
|
|
130
|
+
def to_rules(
|
|
131
|
+
self, errors: Literal["raise", "continue"] = "continue", role: RoleTypes | None = None
|
|
132
|
+
) -> tuple[Rules | None, IssueList] | Rules:
|
|
133
|
+
if self.issue_list.has_errors:
|
|
134
|
+
# In case there were errors during the import, the to_rules method will return None
|
|
135
|
+
return self._return_or_raise(self.issue_list, errors)
|
|
136
|
+
|
|
137
|
+
if len(self.schema.data_models) == 0:
|
|
138
|
+
self.issue_list.append(issues.importing.NoDataModelError("No data model found."))
|
|
139
|
+
return self._return_or_raise(self.issue_list, errors)
|
|
140
|
+
|
|
141
|
+
if len(self.schema.data_models) > 2:
|
|
142
|
+
# Creating a DataModelEntity to convert the data model id to a string.
|
|
143
|
+
self.issue_list.append(
|
|
144
|
+
issues.importing.MultipleDataModelsWarning(
|
|
145
|
+
[str(DataModelEntity.from_id(model.as_id())) for model in self.schema.data_models]
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
data_model = self.schema.data_models[0]
|
|
150
|
+
|
|
151
|
+
properties = SheetList[DMSProperty]()
|
|
152
|
+
ref_properties = SheetList[DMSProperty]()
|
|
153
|
+
for view in self.schema.views:
|
|
154
|
+
view_id = view.as_id()
|
|
155
|
+
view_entity = ViewEntity.from_id(view_id)
|
|
156
|
+
class_entity = view_entity.as_class()
|
|
157
|
+
for prop_id, prop in (view.properties or {}).items():
|
|
158
|
+
dms_property = self._create_dms_property(prop_id, prop, view_entity, class_entity)
|
|
159
|
+
if dms_property is not None:
|
|
160
|
+
if view_id in self.schema.frozen_ids:
|
|
161
|
+
ref_properties.append(dms_property)
|
|
162
|
+
else:
|
|
163
|
+
properties.append(dms_property)
|
|
164
|
+
|
|
165
|
+
data_model_view_ids: set[dm.ViewId] = {
|
|
166
|
+
view.as_id() if isinstance(view, dm.View | dm.ViewApply) else view for view in data_model.views or []
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
metadata = self.metadata or DMSMetadata.from_data_model(data_model)
|
|
170
|
+
metadata.data_model_type = self._infer_data_model_type(metadata.space)
|
|
171
|
+
if ref_properties:
|
|
172
|
+
metadata.schema_ = SchemaCompleteness.extended
|
|
173
|
+
|
|
174
|
+
with _handle_issues(
|
|
175
|
+
self.issue_list,
|
|
176
|
+
) as future:
|
|
177
|
+
user_rules = DMSRules(
|
|
178
|
+
metadata=metadata,
|
|
179
|
+
properties=properties,
|
|
180
|
+
containers=SheetList[DMSContainer](
|
|
181
|
+
data=[
|
|
182
|
+
DMSContainer.from_container(container)
|
|
183
|
+
for container in self.schema.containers
|
|
184
|
+
if container.as_id() not in self.schema.frozen_ids
|
|
185
|
+
]
|
|
186
|
+
),
|
|
187
|
+
views=SheetList[DMSView](
|
|
188
|
+
data=[
|
|
189
|
+
DMSView.from_view(view, in_model=view.as_id() in data_model_view_ids)
|
|
190
|
+
for view in self.schema.views
|
|
191
|
+
if view.as_id() not in self.schema.frozen_ids
|
|
192
|
+
]
|
|
193
|
+
),
|
|
194
|
+
reference=self._create_reference_rules(ref_properties),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if future.result == "failure" or self.issue_list.has_errors:
|
|
198
|
+
return self._return_or_raise(self.issue_list, errors)
|
|
199
|
+
|
|
200
|
+
return self._to_output(user_rules, self.issue_list, errors, role)
|
|
201
|
+
|
|
202
|
+
def _create_reference_rules(self, properties: SheetList[DMSProperty]) -> DMSRules | None:
|
|
203
|
+
if not properties:
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
if len(self.schema.data_models) == 2:
|
|
207
|
+
data_model = self.schema.data_models[1]
|
|
208
|
+
data_model_view_ids: set[dm.ViewId] = {
|
|
209
|
+
view.as_id() if isinstance(view, dm.View | dm.ViewApply) else view for view in data_model.views or []
|
|
210
|
+
}
|
|
211
|
+
metadata = self._create_metadata_from_model(data_model)
|
|
212
|
+
else:
|
|
213
|
+
data_model_view_ids = set()
|
|
214
|
+
now = datetime.now().replace(microsecond=0)
|
|
215
|
+
space = Counter(prop.view.space for prop in properties).most_common(1)[0][0]
|
|
216
|
+
metadata = DMSMetadata(
|
|
217
|
+
schema_=SchemaCompleteness.complete,
|
|
218
|
+
extension=ExtensionCategory.addition,
|
|
219
|
+
space=space,
|
|
220
|
+
external_id="Unknown",
|
|
221
|
+
version="0.1.0",
|
|
222
|
+
creator=["Unknown"],
|
|
223
|
+
created=now,
|
|
224
|
+
updated=now,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
metadata.data_model_type = DataModelType.enterprise
|
|
228
|
+
return DMSRules(
|
|
229
|
+
metadata=metadata,
|
|
230
|
+
properties=properties,
|
|
231
|
+
views=SheetList[DMSView](
|
|
232
|
+
data=[
|
|
233
|
+
DMSView.from_view(view, in_model=not data_model_view_ids or (view.as_id() in data_model_view_ids))
|
|
234
|
+
for view in self.schema.views
|
|
235
|
+
if view.as_id() in self.schema.frozen_ids
|
|
236
|
+
]
|
|
237
|
+
),
|
|
238
|
+
containers=SheetList[DMSContainer](
|
|
239
|
+
data=[
|
|
240
|
+
DMSContainer.from_container(container)
|
|
241
|
+
for container in self.schema.containers
|
|
242
|
+
if container.as_id() in self.schema.frozen_ids
|
|
243
|
+
]
|
|
244
|
+
),
|
|
245
|
+
reference=None,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
def _infer_data_model_type(self, space: str) -> DataModelType:
|
|
249
|
+
if self.schema.referenced_spaces() - {space}:
|
|
250
|
+
# If the data model has containers, views, node types in another space
|
|
251
|
+
# we assume it is a solution model.
|
|
252
|
+
return DataModelType.solution
|
|
253
|
+
else:
|
|
254
|
+
# All containers, views, node types are in the same space as the data model
|
|
255
|
+
return DataModelType.enterprise
|
|
256
|
+
|
|
257
|
+
def _create_dms_property(
|
|
258
|
+
self, prop_id: str, prop: ViewPropertyApply, view_entity: ViewEntity, class_entity: ClassEntity
|
|
259
|
+
) -> DMSProperty | None:
|
|
260
|
+
if isinstance(prop, dm.MappedPropertyApply) and prop.container not in self._container_by_id:
|
|
261
|
+
self.issue_list.append(
|
|
262
|
+
issues.importing.MissingContainerWarning(
|
|
263
|
+
view_id=str(view_entity),
|
|
264
|
+
property_=prop_id,
|
|
265
|
+
container_id=str(ContainerEntity.from_id(prop.container)),
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
return None
|
|
269
|
+
if (
|
|
270
|
+
isinstance(prop, dm.MappedPropertyApply)
|
|
271
|
+
and prop.container_property_identifier not in self._container_by_id[prop.container].properties
|
|
272
|
+
):
|
|
273
|
+
self.issue_list.append(
|
|
274
|
+
issues.importing.MissingContainerPropertyWarning(
|
|
275
|
+
view_id=str(view_entity),
|
|
276
|
+
property_=prop_id,
|
|
277
|
+
container_id=str(ContainerEntity.from_id(prop.container)),
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
return None
|
|
281
|
+
if not isinstance(
|
|
282
|
+
prop,
|
|
283
|
+
dm.MappedPropertyApply
|
|
284
|
+
| SingleEdgeConnectionApply
|
|
285
|
+
| MultiEdgeConnectionApply
|
|
286
|
+
| SingleReverseDirectRelationApply
|
|
287
|
+
| MultiReverseDirectRelationApply,
|
|
288
|
+
):
|
|
289
|
+
self.issue_list.append(
|
|
290
|
+
issues.importing.UnknownPropertyTypeWarning(view_entity.versioned_id, prop_id, type(prop).__name__)
|
|
291
|
+
)
|
|
292
|
+
return None
|
|
293
|
+
|
|
294
|
+
value_type = self._get_value_type(prop, view_entity, prop_id)
|
|
295
|
+
if value_type is None:
|
|
296
|
+
return None
|
|
297
|
+
|
|
298
|
+
return DMSProperty(
|
|
299
|
+
class_=class_entity,
|
|
300
|
+
property_=prop_id,
|
|
301
|
+
description=prop.description,
|
|
302
|
+
name=prop.name,
|
|
303
|
+
connection=self._get_relation_type(prop),
|
|
304
|
+
value_type=value_type,
|
|
305
|
+
is_list=self._get_is_list(prop),
|
|
306
|
+
nullable=self._get_nullable(prop),
|
|
307
|
+
default=self._get_default(prop),
|
|
308
|
+
container=ContainerEntity.from_id(prop.container) if isinstance(prop, dm.MappedPropertyApply) else None,
|
|
309
|
+
container_property=prop.container_property_identifier if isinstance(prop, dm.MappedPropertyApply) else None,
|
|
310
|
+
view=view_entity,
|
|
311
|
+
view_property=prop_id,
|
|
312
|
+
index=self._get_index(prop, prop_id),
|
|
313
|
+
constraint=self._get_constraint(prop, prop_id),
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
def _container_prop_unsafe(self, prop: dm.MappedPropertyApply) -> dm.ContainerProperty:
|
|
317
|
+
"""This method assumes you have already checked that the container with property exists."""
|
|
318
|
+
return self._container_by_id[prop.container].properties[prop.container_property_identifier]
|
|
319
|
+
|
|
320
|
+
def _get_relation_type(self, prop: ViewPropertyApply) -> Literal["edge", "reverse", "direct"] | None:
|
|
321
|
+
if isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "outwards":
|
|
322
|
+
return "edge"
|
|
323
|
+
elif isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "inwards":
|
|
324
|
+
return "reverse"
|
|
325
|
+
elif isinstance(prop, SingleReverseDirectRelationApply | MultiReverseDirectRelationApply):
|
|
326
|
+
return "reverse"
|
|
327
|
+
elif isinstance(prop, dm.MappedPropertyApply) and isinstance(
|
|
328
|
+
self._container_prop_unsafe(prop).type, dm.DirectRelation
|
|
329
|
+
):
|
|
330
|
+
return "direct"
|
|
331
|
+
else:
|
|
332
|
+
return None
|
|
333
|
+
|
|
334
|
+
def _get_value_type(
|
|
335
|
+
self, prop: ViewPropertyApply, view_entity: ViewEntity, prop_id
|
|
336
|
+
) -> DataType | ViewEntity | ViewPropertyEntity | DMSUnknownEntity | None:
|
|
337
|
+
if isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "outwards":
|
|
338
|
+
return ViewEntity.from_id(prop.source)
|
|
339
|
+
elif isinstance(prop, SingleReverseDirectRelationApply | MultiReverseDirectRelationApply):
|
|
340
|
+
return ViewPropertyEntity.from_id(prop.through)
|
|
341
|
+
elif isinstance(prop, SingleEdgeConnectionApply | MultiEdgeConnectionApply) and prop.direction == "inwards":
|
|
342
|
+
return ViewEntity.from_id(prop.source)
|
|
343
|
+
elif isinstance(prop, dm.MappedPropertyApply):
|
|
344
|
+
container_prop = self._container_prop_unsafe(cast(dm.MappedPropertyApply, prop))
|
|
345
|
+
if isinstance(container_prop.type, dm.DirectRelation):
|
|
346
|
+
if prop.source is None:
|
|
347
|
+
# The warning is issued when the DMS Rules are created.
|
|
348
|
+
return DMSUnknownEntity()
|
|
349
|
+
else:
|
|
350
|
+
return ViewEntity.from_id(prop.source)
|
|
351
|
+
else:
|
|
352
|
+
return DataType.load(container_prop.type._type)
|
|
353
|
+
else:
|
|
354
|
+
self.issue_list.append(issues.importing.FailedToInferValueTypeWarning(str(view_entity), prop_id))
|
|
355
|
+
return None
|
|
356
|
+
|
|
357
|
+
def _get_nullable(self, prop: ViewPropertyApply) -> bool | None:
|
|
358
|
+
if isinstance(prop, dm.MappedPropertyApply):
|
|
359
|
+
return self._container_prop_unsafe(prop).nullable
|
|
360
|
+
else:
|
|
361
|
+
return None
|
|
362
|
+
|
|
363
|
+
def _get_is_list(self, prop: ViewPropertyApply) -> bool | None:
|
|
364
|
+
if isinstance(prop, dm.MappedPropertyApply):
|
|
365
|
+
return self._container_prop_unsafe(prop).type.is_list
|
|
366
|
+
elif isinstance(prop, MultiEdgeConnectionApply | MultiReverseDirectRelationApply):
|
|
367
|
+
return True
|
|
368
|
+
elif isinstance(prop, SingleEdgeConnectionApply | SingleReverseDirectRelationApply):
|
|
369
|
+
return False
|
|
370
|
+
else:
|
|
371
|
+
return None
|
|
372
|
+
|
|
373
|
+
def _get_default(self, prop: ViewPropertyApply) -> str | None:
|
|
374
|
+
if isinstance(prop, dm.MappedPropertyApply):
|
|
375
|
+
default = self._container_prop_unsafe(prop).default_value
|
|
376
|
+
if default is not None:
|
|
377
|
+
return str(default)
|
|
378
|
+
return None
|
|
379
|
+
|
|
380
|
+
def _get_index(self, prop: ViewPropertyApply, prop_id) -> list[str] | None:
|
|
381
|
+
if not isinstance(prop, dm.MappedPropertyApply):
|
|
382
|
+
return None
|
|
383
|
+
container = self._container_by_id[prop.container]
|
|
384
|
+
index: list[str] = []
|
|
385
|
+
for index_name, index_obj in (container.indexes or {}).items():
|
|
386
|
+
if isinstance(index_obj, BTreeIndex | InvertedIndex) and prop_id in index_obj.properties:
|
|
387
|
+
index.append(index_name)
|
|
388
|
+
return index or None
|
|
389
|
+
|
|
390
|
+
def _get_constraint(self, prop: ViewPropertyApply, prop_id: str) -> list[str] | None:
|
|
391
|
+
if not isinstance(prop, dm.MappedPropertyApply):
|
|
392
|
+
return None
|
|
393
|
+
container = self._container_by_id[prop.container]
|
|
394
|
+
unique_constraints: list[str] = []
|
|
395
|
+
for constraint_name, constraint_obj in (container.constraints or {}).items():
|
|
396
|
+
if isinstance(constraint_obj, dm.RequiresConstraint):
|
|
397
|
+
# This is handled in the .from_container method of DMSContainer
|
|
398
|
+
continue
|
|
399
|
+
elif isinstance(constraint_obj, dm.UniquenessConstraint) and prop_id in constraint_obj.properties:
|
|
400
|
+
unique_constraints.append(constraint_name)
|
|
401
|
+
elif isinstance(constraint_obj, dm.UniquenessConstraint):
|
|
402
|
+
# This does not apply to this property
|
|
403
|
+
continue
|
|
404
|
+
else:
|
|
405
|
+
self.issue_list.append(
|
|
406
|
+
issues.importing.UnknownContainerConstraintWarning(
|
|
407
|
+
str(ContainerEntity.from_id(prop.container)), prop_id, type(constraint_obj).__name__
|
|
408
|
+
)
|
|
409
|
+
)
|
|
410
|
+
return unique_constraints or None
|
{cognite_neat-0.75.9 → cognite_neat-0.76.0}/cognite/neat/rules/importers/_spreadsheet2rules.py
RENAMED
|
@@ -22,7 +22,15 @@ from cognite.neat.utils.spreadsheet import SpreadsheetRead, read_individual_shee
|
|
|
22
22
|
from ._base import BaseImporter, Rules, _handle_issues
|
|
23
23
|
|
|
24
24
|
SOURCE_SHEET__TARGET_FIELD__HEADERS = [
|
|
25
|
-
(
|
|
25
|
+
(
|
|
26
|
+
"Properties",
|
|
27
|
+
"Properties",
|
|
28
|
+
{
|
|
29
|
+
RoleTypes.domain_expert: "Property",
|
|
30
|
+
RoleTypes.information_architect: "Property",
|
|
31
|
+
RoleTypes.dms_architect: "View Property",
|
|
32
|
+
},
|
|
33
|
+
),
|
|
26
34
|
("Classes", "Classes", "Class"),
|
|
27
35
|
("Containers", "Containers", "Container"),
|
|
28
36
|
("Views", "Views", "View"),
|
|
@@ -131,11 +139,15 @@ class SpreadsheetReader:
|
|
|
131
139
|
)
|
|
132
140
|
return None, read_info_by_sheet
|
|
133
141
|
|
|
134
|
-
for source_sheet_name, target_sheet_name,
|
|
142
|
+
for source_sheet_name, target_sheet_name, headers_input in SOURCE_SHEET__TARGET_FIELD__HEADERS:
|
|
135
143
|
source_sheet_name = self.to_reference_sheet(source_sheet_name) if self._is_reference else source_sheet_name
|
|
136
144
|
|
|
137
145
|
if source_sheet_name not in excel_file.sheet_names:
|
|
138
146
|
continue
|
|
147
|
+
if isinstance(headers_input, dict):
|
|
148
|
+
headers = headers_input[metadata.role]
|
|
149
|
+
else:
|
|
150
|
+
headers = headers_input
|
|
139
151
|
|
|
140
152
|
try:
|
|
141
153
|
sheets[target_sheet_name], read_info_by_sheet[source_sheet_name] = read_individual_sheet(
|
|
@@ -229,12 +241,6 @@ class ExcelImporter(BaseImporter):
|
|
|
229
241
|
role=role,
|
|
230
242
|
)
|
|
231
243
|
|
|
232
|
-
@classmethod
|
|
233
|
-
def _return_or_raise(cls, issue_list: IssueList, errors: Literal["raise", "continue"]) -> tuple[None, IssueList]:
|
|
234
|
-
if errors == "raise":
|
|
235
|
-
raise issue_list.as_errors()
|
|
236
|
-
return None, issue_list
|
|
237
|
-
|
|
238
244
|
|
|
239
245
|
class GoogleSheetImporter(BaseImporter):
|
|
240
246
|
def __init__(self, sheet_id: str, skiprows: int = 1):
|
|
@@ -78,6 +78,9 @@ class NeatValidationError(ValidationIssue, ABC):
|
|
|
78
78
|
all_errors.append(DefaultPydanticError.from_pydantic_error(error))
|
|
79
79
|
return all_errors
|
|
80
80
|
|
|
81
|
+
def as_exception(self) -> Exception:
|
|
82
|
+
return ValueError(self.message())
|
|
83
|
+
|
|
81
84
|
|
|
82
85
|
@dataclass(frozen=True)
|
|
83
86
|
class DefaultPydanticError(NeatValidationError):
|