cognite-neat 0.101.0__py3-none-any.whl → 0.103.0__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/__init__.py +1 -1
- cognite/neat/_app/api/routers/crud.py +1 -1
- cognite/neat/_client/__init__.py +1 -1
- cognite/neat/_client/_api/data_modeling_loaders.py +1 -1
- cognite/neat/_client/_api/schema.py +1 -1
- cognite/neat/_constants.py +5 -1
- cognite/neat/_graph/_tracking/__init__.py +1 -1
- cognite/neat/_graph/extractors/__init__.py +8 -8
- cognite/neat/_graph/extractors/_mock_graph_generator.py +2 -3
- cognite/neat/_graph/loaders/_base.py +1 -1
- cognite/neat/_graph/loaders/_rdf2dms.py +165 -47
- cognite/neat/_graph/queries/_base.py +22 -2
- cognite/neat/_graph/queries/_shared.py +4 -4
- cognite/neat/_graph/transformers/__init__.py +25 -9
- cognite/neat/_graph/transformers/_base.py +1 -1
- cognite/neat/_graph/transformers/_iodd.py +2 -2
- cognite/neat/_graph/transformers/_prune_graph.py +98 -24
- cognite/neat/_graph/transformers/_value_type.py +196 -2
- cognite/neat/_issues/__init__.py +6 -6
- cognite/neat/_issues/_base.py +4 -4
- cognite/neat/_issues/errors/__init__.py +22 -22
- cognite/neat/_issues/formatters.py +1 -1
- cognite/neat/_issues/warnings/__init__.py +20 -18
- cognite/neat/_issues/warnings/_properties.py +7 -0
- cognite/neat/_issues/warnings/user_modeling.py +2 -2
- cognite/neat/_rules/analysis/__init__.py +1 -1
- cognite/neat/_rules/catalog/__init__.py +1 -0
- cognite/neat/_rules/catalog/hello_world_pump.xlsx +0 -0
- cognite/neat/_rules/exporters/__init__.py +5 -5
- cognite/neat/_rules/exporters/_rules2excel.py +12 -6
- cognite/neat/_rules/importers/__init__.py +4 -4
- cognite/neat/_rules/importers/_base.py +7 -3
- cognite/neat/_rules/importers/_dms2rules.py +51 -19
- cognite/neat/_rules/importers/_rdf/__init__.py +1 -1
- cognite/neat/_rules/importers/_rdf/_base.py +2 -2
- cognite/neat/_rules/models/__init__.py +5 -5
- cognite/neat/_rules/models/_base_rules.py +1 -1
- cognite/neat/_rules/models/dms/__init__.py +11 -11
- cognite/neat/_rules/models/dms/_validation.py +16 -10
- cognite/neat/_rules/models/entities/__init__.py +26 -26
- cognite/neat/_rules/models/information/__init__.py +5 -5
- cognite/neat/_rules/models/information/_rules.py +3 -3
- cognite/neat/_rules/models/mapping/_classic2core.yaml +54 -8
- cognite/neat/_rules/transformers/__init__.py +12 -12
- cognite/neat/_rules/transformers/_pipelines.py +10 -5
- cognite/neat/_session/_base.py +71 -0
- cognite/neat/_session/_collector.py +3 -1
- cognite/neat/_session/_drop.py +10 -0
- cognite/neat/_session/_inspect.py +35 -1
- cognite/neat/_session/_mapping.py +5 -0
- cognite/neat/_session/_prepare.py +196 -7
- cognite/neat/_session/_read.py +180 -20
- cognite/neat/_session/_set.py +11 -1
- cognite/neat/_session/_show.py +41 -2
- cognite/neat/_session/_to.py +58 -10
- cognite/neat/_session/engine/__init__.py +1 -1
- cognite/neat/_session/engine/_load.py +3 -1
- cognite/neat/_store/__init__.py +3 -2
- cognite/neat/_store/{_base.py → _graph_store.py} +56 -2
- cognite/neat/_store/_provenance.py +11 -1
- cognite/neat/_store/_rules_store.py +20 -0
- cognite/neat/_utils/auth.py +7 -5
- cognite/neat/_utils/reader/__init__.py +1 -1
- cognite/neat/_version.py +2 -2
- cognite/neat/_workflows/__init__.py +3 -3
- cognite/neat/_workflows/steps/lib/current/graph_extractor.py +1 -1
- cognite/neat/_workflows/steps/lib/current/rules_exporter.py +1 -1
- cognite/neat/_workflows/steps/lib/current/rules_importer.py +2 -2
- cognite/neat/_workflows/steps/lib/io/io_steps.py +3 -3
- {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/METADATA +1 -1
- {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/RECORD +74 -72
- {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/LICENSE +0 -0
- {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/WHEEL +0 -0
- {cognite_neat-0.101.0.dist-info → cognite_neat-0.103.0.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
from typing import cast
|
|
2
|
+
|
|
1
3
|
from rdflib import Graph, Namespace, URIRef
|
|
2
|
-
from rdflib.query import ResultRow
|
|
3
4
|
|
|
5
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
6
|
+
from cognite.neat._shared import Triple
|
|
4
7
|
from cognite.neat._utils.rdf_ import as_neat_compliant_uri
|
|
5
8
|
from cognite.neat._utils.text import sentence_or_string_to_camel
|
|
6
9
|
|
|
@@ -55,12 +58,13 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
|
|
|
55
58
|
|
|
56
59
|
Args:
|
|
57
60
|
target_node_type: RDF.type of edge Node
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
the new predicate to use when attaching the new property to the source node.
|
|
61
|
+
target_property: URIRef of the property that holds the value attached to the intermediate node
|
|
62
|
+
target_property_holding_new_property: URIRef of the property which value will be new
|
|
63
|
+
property that will be added to the source node
|
|
62
64
|
delete_target_node: bool if the intermediate Node and Edge between source Node
|
|
63
65
|
and target property should be deleted. Defaults to False.
|
|
66
|
+
convert_literal_to_uri: bool if the value of the new property should be converted to URIRef. Defaults to False.
|
|
67
|
+
namespace: Namespace to use when converting value to URIRef. Defaults to DEFAULT_NAMESPACE.
|
|
64
68
|
"""
|
|
65
69
|
|
|
66
70
|
description: str = "Attaches a target property from a target node that is connected to a source node."
|
|
@@ -82,25 +86,26 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
|
|
|
82
86
|
def __init__(
|
|
83
87
|
self,
|
|
84
88
|
target_node_type: URIRef,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
target_property_holding_new_property_name: str | None = None,
|
|
89
|
+
target_property: URIRef,
|
|
90
|
+
target_property_holding_new_property: URIRef | None = None,
|
|
88
91
|
delete_target_node: bool = False,
|
|
92
|
+
convert_literal_to_uri: bool = False,
|
|
93
|
+
namespace: Namespace | None = None,
|
|
89
94
|
):
|
|
90
95
|
self.target_node_type = target_node_type
|
|
91
|
-
self.
|
|
92
|
-
self.target_property = self.namespace[target_property]
|
|
96
|
+
self.target_property = target_property
|
|
93
97
|
self.delete_target_node = delete_target_node
|
|
94
|
-
self.
|
|
98
|
+
self.target_property_holding_new_property = target_property_holding_new_property
|
|
99
|
+
self.convert_literal_to_uri = convert_literal_to_uri
|
|
100
|
+
self.namespace = namespace or DEFAULT_NAMESPACE
|
|
95
101
|
|
|
96
102
|
def transform(self, graph) -> None:
|
|
97
103
|
nodes_to_delete: list[tuple] = []
|
|
98
104
|
|
|
99
|
-
if self.
|
|
100
|
-
target_property_holding_new_property_name = self.namespace[self.target_property_holding_new_property_name]
|
|
105
|
+
if self.target_property_holding_new_property is not None:
|
|
101
106
|
query = self._query_template_use_case_b.format(
|
|
102
107
|
target_node_type=self.target_node_type,
|
|
103
|
-
target_property_holding_new_property_name=
|
|
108
|
+
target_property_holding_new_property_name=self.target_property_holding_new_property,
|
|
104
109
|
target_property=self.target_property,
|
|
105
110
|
)
|
|
106
111
|
else:
|
|
@@ -116,15 +121,20 @@ class AttachPropertyFromTargetToSource(BaseTransformer):
|
|
|
116
121
|
new_predicate_value,
|
|
117
122
|
new_property_value,
|
|
118
123
|
) in graph.query(query):
|
|
119
|
-
if self.
|
|
124
|
+
if self.target_property_holding_new_property is not None:
|
|
120
125
|
# Ensure new predicate is URI compliant as we are creating a new predicate
|
|
121
126
|
new_predicate_value_string = sentence_or_string_to_camel(str(new_predicate_value))
|
|
122
127
|
predicate = as_neat_compliant_uri(self.namespace[new_predicate_value_string])
|
|
123
128
|
else:
|
|
124
129
|
predicate = old_predicate
|
|
125
|
-
|
|
126
130
|
# Create new connection from source node to value
|
|
127
|
-
graph.add(
|
|
131
|
+
graph.add(
|
|
132
|
+
(
|
|
133
|
+
source_node,
|
|
134
|
+
predicate,
|
|
135
|
+
(self.namespace[new_property_value] if self.convert_literal_to_uri else new_property_value),
|
|
136
|
+
)
|
|
137
|
+
)
|
|
128
138
|
# Remove old relationship between source node and destination node
|
|
129
139
|
graph.remove((source_node, old_predicate, target_node))
|
|
130
140
|
|
|
@@ -158,7 +168,7 @@ class PruneDanglingNodes(BaseTransformer):
|
|
|
158
168
|
node_prune_types: list of RDF types to prune from the Graph if they are stand-alone Nodes
|
|
159
169
|
"""
|
|
160
170
|
|
|
161
|
-
description: str = "Prunes
|
|
171
|
+
description: str = "Prunes nodes of specific rdf types that do not have any connection to them."
|
|
162
172
|
_query_template = """
|
|
163
173
|
SELECT ?subject
|
|
164
174
|
WHERE {{
|
|
@@ -174,10 +184,74 @@ class PruneDanglingNodes(BaseTransformer):
|
|
|
174
184
|
self.node_prune_types = node_prune_types
|
|
175
185
|
|
|
176
186
|
def transform(self, graph: Graph) -> None:
|
|
177
|
-
for
|
|
178
|
-
|
|
187
|
+
for type_ in self.node_prune_types:
|
|
188
|
+
for (subject,) in list(graph.query(self._query_template.format(rdf_type=type_))): # type: ignore
|
|
189
|
+
graph.remove((subject, None, None))
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class PruneTypes(BaseTransformer):
|
|
193
|
+
"""
|
|
194
|
+
Removes all the instances of specific type
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
description: str = "Prunes nodes of specific rdf types"
|
|
198
|
+
_query_template = """
|
|
199
|
+
SELECT ?subject
|
|
200
|
+
WHERE {{
|
|
201
|
+
?subject a <{rdf_type}> .
|
|
202
|
+
}}
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
def __init__(
|
|
206
|
+
self,
|
|
207
|
+
node_prune_types: list[URIRef],
|
|
208
|
+
):
|
|
209
|
+
self.node_prune_types = node_prune_types
|
|
210
|
+
|
|
211
|
+
def transform(self, graph: Graph) -> None:
|
|
212
|
+
for type_ in self.node_prune_types:
|
|
213
|
+
for (subject,) in list(graph.query(self._query_template.format(rdf_type=type_))): # type: ignore
|
|
214
|
+
graph.remove((subject, None, None))
|
|
179
215
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
216
|
+
|
|
217
|
+
class PruneDeadEndEdges(BaseTransformer):
|
|
218
|
+
"""
|
|
219
|
+
Removes all the triples where object is a node that is not found in graph
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
|
|
223
|
+
_query_template = """
|
|
224
|
+
SELECT ?subject ?predicate ?object
|
|
225
|
+
WHERE {
|
|
226
|
+
?subject ?predicate ?object .
|
|
227
|
+
FILTER (isIRI(?object) && ?predicate != rdf:type)
|
|
228
|
+
FILTER NOT EXISTS {?object ?p ?o .}
|
|
229
|
+
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
def transform(self, graph: Graph) -> None:
|
|
235
|
+
for triple in graph.query(self._query_template):
|
|
236
|
+
graph.remove(cast(Triple, triple))
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class PruneInstancesOfUnknownType(BaseTransformer):
|
|
240
|
+
"""
|
|
241
|
+
Removes all the triples where object is a node that is not found in graph
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
description: str = "Prunes the graph of specified rdf types that do not have connections to other nodes."
|
|
245
|
+
_query_template = """
|
|
246
|
+
SELECT DISTINCT ?subject
|
|
247
|
+
WHERE {
|
|
248
|
+
?subject ?p ?o .
|
|
249
|
+
FILTER NOT EXISTS {?subject a ?object .}
|
|
250
|
+
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
def transform(self, graph: Graph) -> None:
|
|
256
|
+
for (subject,) in graph.query(self._query_template): # type: ignore
|
|
257
|
+
graph.remove((subject, None, None))
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
import warnings
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import Any, cast
|
|
4
|
+
from urllib.parse import quote
|
|
5
|
+
|
|
6
|
+
import rdflib
|
|
7
|
+
from rdflib import RDF, XSD, Graph, Namespace, URIRef
|
|
2
8
|
|
|
3
9
|
from cognite.neat._constants import UNKNOWN_TYPE
|
|
4
10
|
from cognite.neat._graph.queries import Queries
|
|
5
|
-
from cognite.neat.
|
|
11
|
+
from cognite.neat._issues.warnings import NeatValueWarning, PropertyDataTypeConversionWarning
|
|
12
|
+
from cognite.neat._utils.auxiliary import string_to_ideal_type
|
|
13
|
+
from cognite.neat._utils.collection_ import iterate_progress_bar
|
|
14
|
+
from cognite.neat._utils.rdf_ import get_namespace, remove_namespace_from_uri
|
|
6
15
|
|
|
7
16
|
from ._base import BaseTransformer
|
|
8
17
|
|
|
@@ -64,3 +73,188 @@ class SplitMultiValueProperty(BaseTransformer):
|
|
|
64
73
|
graph.remove((s, property_uri, o))
|
|
65
74
|
new_property = URIRef(f"{property_uri}_{remove_namespace_from_uri(value_type_uri)}")
|
|
66
75
|
graph.add((s, new_property, o))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ConvertLiteral(BaseTransformer):
|
|
79
|
+
description: str = "ConvertLiteral is a transformer that improve data typing of a literal value."
|
|
80
|
+
_use_only_once: bool = False
|
|
81
|
+
_need_changes = frozenset({})
|
|
82
|
+
|
|
83
|
+
_count_by_properties = """SELECT (COUNT(?value) AS ?valueCount)
|
|
84
|
+
WHERE {{
|
|
85
|
+
?instance a <{subject_type}> .
|
|
86
|
+
?instance <{subject_predicate}> ?value
|
|
87
|
+
FILTER(isLiteral(?value))
|
|
88
|
+
}}"""
|
|
89
|
+
|
|
90
|
+
_count_by_properties_uri = """SELECT (COUNT(?value) AS ?valueCount)
|
|
91
|
+
WHERE {{
|
|
92
|
+
?instance a <{subject_type}> .
|
|
93
|
+
?instance <{subject_predicate}> ?value
|
|
94
|
+
FILTER(isIRI(?value))
|
|
95
|
+
}}"""
|
|
96
|
+
|
|
97
|
+
_properties = """SELECT ?instance ?value
|
|
98
|
+
WHERE {{
|
|
99
|
+
?instance a <{subject_type}> .
|
|
100
|
+
?instance <{subject_predicate}> ?value
|
|
101
|
+
|
|
102
|
+
FILTER(isLiteral(?value))
|
|
103
|
+
|
|
104
|
+
}}"""
|
|
105
|
+
|
|
106
|
+
def __init__(
|
|
107
|
+
self,
|
|
108
|
+
subject_type: URIRef,
|
|
109
|
+
subject_predicate: URIRef,
|
|
110
|
+
conversion: Callable[[Any], Any] | None = None,
|
|
111
|
+
) -> None:
|
|
112
|
+
self.subject_type = subject_type
|
|
113
|
+
self.subject_predicate = subject_predicate
|
|
114
|
+
self.conversion = conversion or string_to_ideal_type
|
|
115
|
+
self._type_name = remove_namespace_from_uri(subject_type)
|
|
116
|
+
self._property_name = remove_namespace_from_uri(subject_predicate)
|
|
117
|
+
|
|
118
|
+
def transform(self, graph: Graph) -> None:
|
|
119
|
+
count_connection_query = self._count_by_properties_uri.format(
|
|
120
|
+
subject_type=self.subject_type, subject_predicate=self.subject_predicate
|
|
121
|
+
)
|
|
122
|
+
connection_count_res = list(graph.query(count_connection_query))
|
|
123
|
+
connection_count = int(connection_count_res[0][0]) # type: ignore [index, arg-type]
|
|
124
|
+
|
|
125
|
+
if connection_count > 0:
|
|
126
|
+
warnings.warn(
|
|
127
|
+
NeatValueWarning(
|
|
128
|
+
f"Skipping {connection_count} of {self._type_name}.{self._property_name} "
|
|
129
|
+
f"as these are connections and not data values."
|
|
130
|
+
),
|
|
131
|
+
stacklevel=2,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
count_query = self._count_by_properties.format(
|
|
135
|
+
subject_type=self.subject_type, subject_predicate=self.subject_predicate
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
property_count_res = list(graph.query(count_query))
|
|
139
|
+
property_count = int(property_count_res[0][0]) # type: ignore [index, arg-type]
|
|
140
|
+
iterate_query = self._properties.format(
|
|
141
|
+
subject_type=self.subject_type, subject_predicate=self.subject_predicate
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
for instance, literal in iterate_progress_bar( # type: ignore[misc]
|
|
145
|
+
graph.query(iterate_query),
|
|
146
|
+
total=property_count,
|
|
147
|
+
description=f"Converting {self._type_name}.{self._property_name}.",
|
|
148
|
+
):
|
|
149
|
+
value = cast(rdflib.Literal, literal).toPython()
|
|
150
|
+
try:
|
|
151
|
+
converted_value = self.conversion(value)
|
|
152
|
+
except Exception as e:
|
|
153
|
+
warnings.warn(
|
|
154
|
+
PropertyDataTypeConversionWarning(str(instance), self._type_name, self._property_name, str(e)),
|
|
155
|
+
stacklevel=2,
|
|
156
|
+
)
|
|
157
|
+
continue
|
|
158
|
+
|
|
159
|
+
graph.add((instance, self.subject_predicate, rdflib.Literal(converted_value)))
|
|
160
|
+
graph.remove((instance, self.subject_predicate, literal))
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class LiteralToEntity(BaseTransformer):
|
|
164
|
+
description = "Converts a literal value to new entity"
|
|
165
|
+
|
|
166
|
+
_count_properties_of_type = """SELECT (COUNT(?property) AS ?propertyCount)
|
|
167
|
+
WHERE {{
|
|
168
|
+
?instance a <{subject_type}> .
|
|
169
|
+
?instance <{subject_predicate}> ?property
|
|
170
|
+
FILTER(isLiteral(?property))
|
|
171
|
+
}}"""
|
|
172
|
+
_count_connections_of_type = """SELECT (COUNT(?property) AS ?propertyCount)
|
|
173
|
+
WHERE {{
|
|
174
|
+
?instance a <{subject_type}> .
|
|
175
|
+
?instance <{subject_predicate}> ?property
|
|
176
|
+
FILTER(isIRI(?property))
|
|
177
|
+
}}"""
|
|
178
|
+
|
|
179
|
+
_properties_of_type = """SELECT ?instance ?property
|
|
180
|
+
WHERE {{
|
|
181
|
+
?instance a <{subject_type}> .
|
|
182
|
+
?instance <{subject_predicate}> ?property
|
|
183
|
+
FILTER(isLiteral(?property))
|
|
184
|
+
}}"""
|
|
185
|
+
|
|
186
|
+
_count_properties = """SELECT (COUNT(?property) AS ?propertyCount)
|
|
187
|
+
WHERE {{
|
|
188
|
+
?instance <{subject_predicate}> ?property
|
|
189
|
+
FILTER(isLiteral(?property))
|
|
190
|
+
}}"""
|
|
191
|
+
_count_connections = """SELECT (COUNT(?property) AS ?propertyCount)
|
|
192
|
+
WHERE {{
|
|
193
|
+
?instance <{subject_predicate}> ?property
|
|
194
|
+
FILTER(isIRI(?property))
|
|
195
|
+
}}"""
|
|
196
|
+
_properties = """SELECT ?instance ?property
|
|
197
|
+
WHERE {{
|
|
198
|
+
?instance <{subject_predicate}> ?property
|
|
199
|
+
FILTER(isLiteral(?property))
|
|
200
|
+
}}"""
|
|
201
|
+
|
|
202
|
+
def __init__(
|
|
203
|
+
self, subject_type: URIRef | None, subject_predicate: URIRef, entity_type: str, new_property: str | None = None
|
|
204
|
+
) -> None:
|
|
205
|
+
self.subject_type = subject_type
|
|
206
|
+
self.subject_predicate = subject_predicate
|
|
207
|
+
self.entity_type = entity_type
|
|
208
|
+
self.new_property = new_property
|
|
209
|
+
|
|
210
|
+
def transform(self, graph: Graph) -> None:
|
|
211
|
+
if self.subject_type is None:
|
|
212
|
+
count_query = self._count_properties.format(subject_predicate=self.subject_predicate)
|
|
213
|
+
iterate_query = self._properties.format(subject_predicate=self.subject_predicate)
|
|
214
|
+
connection_count_query = self._count_connections.format(subject_predicate=self.subject_predicate)
|
|
215
|
+
else:
|
|
216
|
+
count_query = self._count_properties_of_type.format(
|
|
217
|
+
subject_type=self.subject_type, subject_predicate=self.subject_predicate
|
|
218
|
+
)
|
|
219
|
+
iterate_query = self._properties_of_type.format(
|
|
220
|
+
subject_type=self.subject_type, subject_predicate=self.subject_predicate
|
|
221
|
+
)
|
|
222
|
+
connection_count_query = self._count_connections_of_type.format(
|
|
223
|
+
subject_type=self.subject_type, subject_predicate=self.subject_predicate
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
connection_count_res = list(graph.query(connection_count_query))
|
|
227
|
+
connection_count = int(connection_count_res[0][0]) # type: ignore [index, arg-type]
|
|
228
|
+
if connection_count > 0:
|
|
229
|
+
warnings.warn(
|
|
230
|
+
NeatValueWarning(
|
|
231
|
+
f"Skipping {connection_count} of {remove_namespace_from_uri(self.subject_predicate)} "
|
|
232
|
+
f"as these are connections and not data values."
|
|
233
|
+
),
|
|
234
|
+
stacklevel=2,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
property_count_res = list(graph.query(count_query))
|
|
238
|
+
property_count = int(property_count_res[0][0]) # type: ignore [index, arg-type]
|
|
239
|
+
|
|
240
|
+
instance: URIRef
|
|
241
|
+
description = f"Creating {remove_namespace_from_uri(self.subject_predicate)}."
|
|
242
|
+
if self.subject_type is not None:
|
|
243
|
+
description = (
|
|
244
|
+
f"Creating {remove_namespace_from_uri(self.subject_type)}."
|
|
245
|
+
f"{remove_namespace_from_uri(self.subject_predicate)}."
|
|
246
|
+
)
|
|
247
|
+
for instance, literal in iterate_progress_bar( # type: ignore[misc, assignment]
|
|
248
|
+
graph.query(iterate_query),
|
|
249
|
+
total=property_count,
|
|
250
|
+
description=description,
|
|
251
|
+
):
|
|
252
|
+
value = cast(rdflib.Literal, literal).toPython()
|
|
253
|
+
namespace = Namespace(get_namespace(instance))
|
|
254
|
+
entity_type = namespace[self.entity_type]
|
|
255
|
+
new_entity = namespace[f"{self.entity_type}_{quote(value)!s}"]
|
|
256
|
+
graph.add((new_entity, RDF.type, entity_type))
|
|
257
|
+
if self.new_property is not None:
|
|
258
|
+
graph.add((new_entity, namespace[self.new_property], rdflib.Literal(value)))
|
|
259
|
+
graph.add((instance, self.subject_predicate, new_entity))
|
|
260
|
+
graph.remove((instance, self.subject_predicate, literal))
|
cognite/neat/_issues/__init__.py
CHANGED
|
@@ -15,14 +15,14 @@ from ._base import (
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
__all__ = [
|
|
18
|
-
"NeatIssue",
|
|
19
|
-
"NeatError",
|
|
20
|
-
"NeatWarning",
|
|
21
18
|
"DefaultWarning",
|
|
22
|
-
"
|
|
19
|
+
"FutureResult",
|
|
23
20
|
"IssueList",
|
|
24
21
|
"MultiValueError",
|
|
25
|
-
"
|
|
22
|
+
"NeatError",
|
|
23
|
+
"NeatIssue",
|
|
24
|
+
"NeatIssueList",
|
|
25
|
+
"NeatWarning",
|
|
26
26
|
"catch_issues",
|
|
27
|
-
"
|
|
27
|
+
"catch_warnings",
|
|
28
28
|
]
|
cognite/neat/_issues/_base.py
CHANGED
|
@@ -32,12 +32,12 @@ else:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
__all__ = [
|
|
35
|
-
"NeatIssue",
|
|
36
|
-
"NeatError",
|
|
37
|
-
"NeatWarning",
|
|
38
35
|
"DefaultWarning",
|
|
39
|
-
"NeatIssueList",
|
|
40
36
|
"MultiValueError",
|
|
37
|
+
"NeatError",
|
|
38
|
+
"NeatIssue",
|
|
39
|
+
"NeatIssueList",
|
|
40
|
+
"NeatWarning",
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
T_Identifier = TypeVar("T_Identifier", bound=Hashable)
|
|
@@ -38,40 +38,40 @@ from ._workflow import (
|
|
|
38
38
|
)
|
|
39
39
|
|
|
40
40
|
__all__ = [
|
|
41
|
+
"AuthorizationError",
|
|
42
|
+
"CDFMissingClientError",
|
|
43
|
+
"DefaultPydanticError",
|
|
44
|
+
"FileMissingRequiredFieldError",
|
|
45
|
+
"FileNotAFileError",
|
|
46
|
+
"FileNotFoundNeatError",
|
|
47
|
+
"FileReadError",
|
|
48
|
+
"FileTypeUnexpectedError",
|
|
41
49
|
"NeatError",
|
|
42
|
-
"NeatValueError",
|
|
43
50
|
"NeatImportError",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
51
|
+
"NeatTypeError",
|
|
52
|
+
"NeatValueError",
|
|
46
53
|
"NeatYamlError",
|
|
47
|
-
"
|
|
48
|
-
"ResourceCreationError",
|
|
49
|
-
"FileNotFoundNeatError",
|
|
50
|
-
"FileMissingRequiredFieldError",
|
|
54
|
+
"PropertyDefinitionDuplicatedError",
|
|
51
55
|
"PropertyDefinitionError",
|
|
52
|
-
"
|
|
56
|
+
"PropertyMappingDuplicatedError",
|
|
53
57
|
"PropertyNotFoundError",
|
|
54
|
-
"
|
|
58
|
+
"PropertyTypeNotSupportedError",
|
|
59
|
+
"RegexViolationError",
|
|
55
60
|
"ResourceChangedError",
|
|
61
|
+
"ResourceConversionError",
|
|
62
|
+
"ResourceCreationError",
|
|
56
63
|
"ResourceDuplicatedError",
|
|
57
|
-
"ResourceRetrievalError",
|
|
58
|
-
"ResourceNotFoundError",
|
|
59
64
|
"ResourceError",
|
|
60
|
-
"ResourceNotDefinedError",
|
|
61
65
|
"ResourceMissingIdentifierError",
|
|
62
|
-
"
|
|
63
|
-
"
|
|
66
|
+
"ResourceNotDefinedError",
|
|
67
|
+
"ResourceNotFoundError",
|
|
68
|
+
"ResourceRetrievalError",
|
|
69
|
+
"ReversedConnectionNotFeasibleError",
|
|
70
|
+
"RowError",
|
|
64
71
|
"WorkFlowMissingDataError",
|
|
72
|
+
"WorkflowConfigurationNotSetError",
|
|
65
73
|
"WorkflowStepNotInitializedError",
|
|
66
74
|
"WorkflowStepOutputError",
|
|
67
|
-
"FileTypeUnexpectedError",
|
|
68
|
-
"FileNotAFileError",
|
|
69
|
-
"DefaultPydanticError",
|
|
70
|
-
"PropertyMappingDuplicatedError",
|
|
71
|
-
"RowError",
|
|
72
|
-
"NeatTypeError",
|
|
73
|
-
"ReversedConnectionNotFeasibleError",
|
|
74
|
-
"CDFMissingClientError",
|
|
75
75
|
]
|
|
76
76
|
|
|
77
77
|
_NEAT_ERRORS_BY_NAME = {error.__name__: error for error in _get_subclasses(NeatError, include_base=True)}
|
|
@@ -26,6 +26,7 @@ from ._models import (
|
|
|
26
26
|
UserModelingWarning,
|
|
27
27
|
)
|
|
28
28
|
from ._properties import (
|
|
29
|
+
PropertyDataTypeConversionWarning,
|
|
29
30
|
PropertyDefinitionDuplicatedWarning,
|
|
30
31
|
PropertyNotFoundWarning,
|
|
31
32
|
PropertyOverwritingWarning,
|
|
@@ -43,38 +44,39 @@ from ._resources import (
|
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
__all__ = [
|
|
47
|
+
"BreakingModelingPrincipleWarning",
|
|
48
|
+
"CDFAuthWarning",
|
|
49
|
+
"CDFMaxIterationsWarning",
|
|
50
|
+
"CDFNotSupportedWarning",
|
|
46
51
|
"DefaultWarning",
|
|
47
|
-
"FileReadWarning",
|
|
48
|
-
"FileMissingRequiredFieldWarning",
|
|
49
52
|
"FileItemNotSupportedWarning",
|
|
53
|
+
"FileMissingRequiredFieldWarning",
|
|
54
|
+
"FileReadWarning",
|
|
50
55
|
"FileTypeUnexpectedWarning",
|
|
51
56
|
"NeatValueWarning",
|
|
57
|
+
"NotSupportedHasDataFilterLimitWarning",
|
|
58
|
+
"NotSupportedViewContainerLimitWarning",
|
|
52
59
|
"NotSupportedWarning",
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
60
|
+
"PrincipleMatchingSpaceAndVersionWarning",
|
|
61
|
+
"PrincipleOneModelOneSpaceWarning",
|
|
62
|
+
"PrincipleSolutionBuildsOnEnterpriseWarning",
|
|
63
|
+
"PropertyDataTypeConversionWarning",
|
|
56
64
|
"PropertyDefinitionDuplicatedWarning",
|
|
57
|
-
"PropertyTypeNotSupportedWarning",
|
|
58
65
|
"PropertyNotFoundWarning",
|
|
59
|
-
"PropertyValueTypeUndefinedWarning",
|
|
60
66
|
"PropertyOverwritingWarning",
|
|
61
67
|
"PropertySkippedWarning",
|
|
62
|
-
"
|
|
63
|
-
"
|
|
68
|
+
"PropertyTypeNotSupportedWarning",
|
|
69
|
+
"PropertyValueTypeUndefinedWarning",
|
|
64
70
|
"RegexViolationWarning",
|
|
71
|
+
"ResourceNeatWarning",
|
|
65
72
|
"ResourceNotFoundWarning",
|
|
66
|
-
"ResourceTypeNotSupportedWarning",
|
|
67
|
-
"ResourceRetrievalWarning",
|
|
68
73
|
"ResourceRegexViolationWarning",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"NotSupportedViewContainerLimitWarning",
|
|
73
|
-
"NotSupportedHasDataFilterLimitWarning",
|
|
74
|
+
"ResourceRetrievalWarning",
|
|
75
|
+
"ResourceTypeNotSupportedWarning",
|
|
76
|
+
"ResourcesDuplicatedWarning",
|
|
74
77
|
"UndefinedViewWarning",
|
|
75
|
-
"
|
|
78
|
+
"UserModelingWarning",
|
|
76
79
|
"user_modeling",
|
|
77
|
-
"CDFMaxIterationsWarning",
|
|
78
80
|
]
|
|
79
81
|
|
|
80
82
|
_NEAT_WARNINGS_BY_NAME = {warning.__name__: warning for warning in _get_subclasses(NeatWarning, include_base=True)}
|
|
@@ -70,3 +70,10 @@ class PropertySkippedWarning(PropertyWarning[T_Identifier]):
|
|
|
70
70
|
which is skipped. {reason}."""
|
|
71
71
|
|
|
72
72
|
reason: str
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass(unsafe_hash=True)
|
|
76
|
+
class PropertyDataTypeConversionWarning(PropertyWarning[T_Identifier]):
|
|
77
|
+
"""The {resource_type} with identifier {identifier} failed to convert the property {property_name}: {error}"""
|
|
78
|
+
|
|
79
|
+
error: str
|
|
@@ -12,12 +12,12 @@ from cognite.neat._constants import DMS_CONTAINER_PROPERTY_SIZE_LIMIT
|
|
|
12
12
|
from ._models import UserModelingWarning
|
|
13
13
|
|
|
14
14
|
__all__ = [
|
|
15
|
+
"ContainerPropertyLimitWarning",
|
|
15
16
|
"DirectRelationMissingSourceWarning",
|
|
16
17
|
"EmptyContainerWarning",
|
|
17
18
|
"HasDataFilterOnNoPropertiesViewWarning",
|
|
18
|
-
"NodeTypeFilterOnParentViewWarning",
|
|
19
19
|
"HasDataFilterOnViewWithReferencesWarning",
|
|
20
|
-
"
|
|
20
|
+
"NodeTypeFilterOnParentViewWarning",
|
|
21
21
|
"NotNeatSupportedFilterWarning",
|
|
22
22
|
"ParentInDifferentSpaceWarning",
|
|
23
23
|
]
|
|
Binary file
|
|
@@ -7,15 +7,15 @@ from ._rules2yaml import YAMLExporter
|
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
"BaseExporter",
|
|
10
|
-
"DMSExporter",
|
|
11
10
|
"CDFExporter",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
11
|
+
"DMSExporter",
|
|
12
|
+
"ExcelExporter",
|
|
14
13
|
"GraphExporter",
|
|
14
|
+
"InstanceTemplateExporter",
|
|
15
|
+
"OWLExporter",
|
|
15
16
|
"SHACLExporter",
|
|
16
|
-
"
|
|
17
|
+
"SemanticDataModelExporter",
|
|
17
18
|
"YAMLExporter",
|
|
18
|
-
"InstanceTemplateExporter",
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
|