cognite-neat 0.123.8__py3-none-any.whl → 0.123.10__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/_data_model/_constants.py +2 -6
- cognite/neat/core/_data_model/models/conceptual/_validation.py +3 -3
- cognite/neat/core/_data_model/models/physical/_validation.py +136 -4
- cognite/neat/core/_data_model/models/physical/_verified.py +50 -1
- cognite/neat/core/_issues/_base.py +1 -1
- cognite/neat/core/_issues/errors/__init__.py +2 -0
- cognite/neat/core/_issues/errors/_properties.py +11 -0
- cognite/neat/core/_issues/warnings/__init__.py +2 -0
- cognite/neat/core/_issues/warnings/_properties.py +11 -0
- {cognite_neat-0.123.8.dist-info → cognite_neat-0.123.10.dist-info}/METADATA +1 -1
- {cognite_neat-0.123.8.dist-info → cognite_neat-0.123.10.dist-info}/RECORD +14 -14
- {cognite_neat-0.123.8.dist-info → cognite_neat-0.123.10.dist-info}/WHEEL +0 -0
- {cognite_neat-0.123.8.dist-info → cognite_neat-0.123.10.dist-info}/licenses/LICENSE +0 -0
cognite/neat/_version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "0.123.
|
|
1
|
+
__version__ = "0.123.10"
|
|
2
2
|
__engine__ = "^2.0.4"
|
|
@@ -111,12 +111,8 @@ PHYSICAL_PROPERTY_ID_COMPLIANCE_REGEX = (
|
|
|
111
111
|
rf"(?!^({'|'.join(get_reserved_words('property'))})$)"
|
|
112
112
|
r"(^[a-zA-Z][a-zA-Z0-9_]{0,253}[a-zA-Z0-9]?$)"
|
|
113
113
|
)
|
|
114
|
-
CONCEPT_ID_COMPLIANCE_REGEX =
|
|
115
|
-
rf"(?!^({'|'.join(get_reserved_words('concept'))})$)"
|
|
116
|
-
r"(^[a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]?$)"
|
|
117
|
-
)
|
|
114
|
+
CONCEPT_ID_COMPLIANCE_REGEX = r"^[a-zA-Z0-9._~?@!$&'*+,;=%-]+$"
|
|
118
115
|
|
|
119
|
-
INFORMATION_PROPERTY_ID_COMPLIANCE_REGEX = r"^(\*)|(?!^(Property|property)$)(^[a-zA-Z0-9._-]{0,253}[a-zA-Z0-9]?$)"
|
|
120
116
|
VERSION_COMPLIANCE_REGEX = r"^[a-zA-Z0-9]([.a-zA-Z0-9_-]{0,41}[a-zA-Z0-9])?$"
|
|
121
117
|
|
|
122
118
|
|
|
@@ -156,7 +152,7 @@ class _Patterns:
|
|
|
156
152
|
|
|
157
153
|
@cached_property
|
|
158
154
|
def conceptual_property_id_compliance(self) -> re.Pattern[str]:
|
|
159
|
-
return re.compile(
|
|
155
|
+
return re.compile(CONCEPT_ID_COMPLIANCE_REGEX)
|
|
160
156
|
|
|
161
157
|
@cached_property
|
|
162
158
|
def version_compliance(self) -> re.Pattern[str]:
|
|
@@ -46,7 +46,7 @@ class ConceptualValidation:
|
|
|
46
46
|
self._parent_concept_defined()
|
|
47
47
|
self._referenced_classes_exist()
|
|
48
48
|
self._referenced_value_types_exist()
|
|
49
|
-
self.
|
|
49
|
+
self._regex_compliance_with_physical_data_model()
|
|
50
50
|
|
|
51
51
|
return self.issue_list
|
|
52
52
|
|
|
@@ -180,7 +180,7 @@ class ConceptualValidation:
|
|
|
180
180
|
)
|
|
181
181
|
)
|
|
182
182
|
|
|
183
|
-
def
|
|
183
|
+
def _regex_compliance_with_physical_data_model(self) -> None:
|
|
184
184
|
"""Check regex compliance with DMS of properties, classes and value types."""
|
|
185
185
|
|
|
186
186
|
for prop_ in self._properties:
|
|
@@ -239,7 +239,7 @@ class ConceptualValidation:
|
|
|
239
239
|
ResourceRegexViolationWarning(
|
|
240
240
|
concepts.concept,
|
|
241
241
|
"Concept",
|
|
242
|
-
"Concepts sheet,
|
|
242
|
+
"Concepts sheet, Concept column",
|
|
243
243
|
PATTERNS.view_id_compliance.pattern,
|
|
244
244
|
)
|
|
245
245
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
from collections import Counter, defaultdict
|
|
3
3
|
from collections.abc import Mapping
|
|
4
|
+
from dataclasses import dataclass
|
|
4
5
|
from functools import lru_cache
|
|
5
6
|
|
|
6
7
|
from cognite.client import data_modeling as dm
|
|
@@ -24,12 +25,14 @@ from cognite.neat.core._constants import (
|
|
|
24
25
|
from cognite.neat.core._data_model.models.data_types import DataType
|
|
25
26
|
from cognite.neat.core._data_model.models.entities import ContainerEntity, RawFilter
|
|
26
27
|
from cognite.neat.core._data_model.models.entities._single_value import (
|
|
28
|
+
ContainerIndexEntity,
|
|
27
29
|
ViewEntity,
|
|
28
30
|
)
|
|
29
31
|
from cognite.neat.core._issues import IssueList, NeatError
|
|
30
32
|
from cognite.neat.core._issues.errors import (
|
|
31
33
|
CDFMissingClientError,
|
|
32
34
|
PropertyDefinitionDuplicatedError,
|
|
35
|
+
PropertyInvalidDefinitionError,
|
|
33
36
|
PropertyMappingDuplicatedError,
|
|
34
37
|
PropertyNotFoundError,
|
|
35
38
|
ResourceDuplicatedError,
|
|
@@ -55,6 +58,21 @@ from cognite.neat.core._utils.text import humanize_collection
|
|
|
55
58
|
from ._verified import PhysicalDataModel, PhysicalProperty
|
|
56
59
|
|
|
57
60
|
|
|
61
|
+
@dataclass
|
|
62
|
+
class _ContainerPropertyIndex:
|
|
63
|
+
"""This is a helper class used in the indices validation
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
location: The index of the property in the properties list.
|
|
67
|
+
property_: The physical property associated with the container.
|
|
68
|
+
index: The index entity that defines the container property.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
location: int
|
|
72
|
+
property_: PhysicalProperty
|
|
73
|
+
index: ContainerIndexEntity
|
|
74
|
+
|
|
75
|
+
|
|
58
76
|
class PhysicalValidation:
|
|
59
77
|
"""This class does all the validation of the physical data model that
|
|
60
78
|
have dependencies between components."""
|
|
@@ -145,6 +163,7 @@ class PhysicalValidation:
|
|
|
145
163
|
all_properties_by_ids = {**ref_properties_by_ids, **properties_by_ids}
|
|
146
164
|
view_properties_by_id = self._as_view_properties_by_id(properties_by_ids)
|
|
147
165
|
parents_view_ids_by_child_id = self._parent_view_ids_by_child_id(all_views_by_id)
|
|
166
|
+
container_properties_by_id = self._create_container_properties_by_id()
|
|
148
167
|
|
|
149
168
|
issue_list = IssueList()
|
|
150
169
|
|
|
@@ -154,7 +173,8 @@ class PhysicalValidation:
|
|
|
154
173
|
# Neat DMS classes Validation
|
|
155
174
|
# These are errors that can only happen due to the format of the Neat DMS classes
|
|
156
175
|
issue_list.extend(self._validate_raw_filter())
|
|
157
|
-
issue_list.extend(self._consistent_container_properties())
|
|
176
|
+
issue_list.extend(self._consistent_container_properties(container_properties_by_id))
|
|
177
|
+
issue_list.extend(self._valid_composite_container_indices(container_properties_by_id))
|
|
158
178
|
issue_list.extend(self._validate_value_type_existence())
|
|
159
179
|
issue_list.extend(
|
|
160
180
|
self._validate_property_referenced_views_and_containers_exists(all_views_by_id, all_containers_by_id)
|
|
@@ -320,13 +340,27 @@ class PhysicalValidation:
|
|
|
320
340
|
parents_by_view[view_id] = get_parents(view_id)
|
|
321
341
|
return parents_by_view
|
|
322
342
|
|
|
323
|
-
def
|
|
343
|
+
def _create_container_properties_by_id(
|
|
344
|
+
self,
|
|
345
|
+
) -> dict[tuple[ContainerEntity, str], list[tuple[int, PhysicalProperty]]]:
|
|
346
|
+
"""Create a mapping of container properties with their location in the properties list.
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
dict[tuple[ContainerEntity, str], list[tuple[int, PhysicalProperty]]]: A dictionary where the key is a tuple
|
|
350
|
+
of (ContainerEntity, property name) and the value is a list of tuples of (int, PhysicalProperty) where
|
|
351
|
+
int is the index of the property in the properties list and PhysicalProperty is the property itself.
|
|
352
|
+
"""
|
|
324
353
|
container_properties_by_id: dict[tuple[ContainerEntity, str], list[tuple[int, PhysicalProperty]]] = defaultdict(
|
|
325
354
|
list
|
|
326
355
|
)
|
|
327
356
|
for prop_no, prop in enumerate(self._properties):
|
|
328
357
|
if prop.container and prop.container_property:
|
|
329
358
|
container_properties_by_id[(prop.container, prop.container_property)].append((prop_no, prop))
|
|
359
|
+
return container_properties_by_id
|
|
360
|
+
|
|
361
|
+
def _consistent_container_properties(
|
|
362
|
+
self, container_properties_by_id: dict[tuple[ContainerEntity, str], list[tuple[int, PhysicalProperty]]]
|
|
363
|
+
) -> IssueList:
|
|
330
364
|
properties_sheet = self._read_info_by_spreadsheet.get("Properties")
|
|
331
365
|
errors = IssueList()
|
|
332
366
|
for (container, prop_name), properties in container_properties_by_id.items():
|
|
@@ -392,11 +426,11 @@ class PhysicalValidation:
|
|
|
392
426
|
)
|
|
393
427
|
)
|
|
394
428
|
index_definitions = {
|
|
395
|
-
",".join([index
|
|
429
|
+
",".join([str(index) for index in prop.index]) for _, prop in properties if prop.index is not None
|
|
396
430
|
}
|
|
397
431
|
if len(index_definitions) > 1:
|
|
398
432
|
errors.append(
|
|
399
|
-
PropertyDefinitionDuplicatedError
|
|
433
|
+
PropertyDefinitionDuplicatedError(
|
|
400
434
|
container_id,
|
|
401
435
|
"container",
|
|
402
436
|
prop_name,
|
|
@@ -422,6 +456,104 @@ class PhysicalValidation:
|
|
|
422
456
|
|
|
423
457
|
return errors
|
|
424
458
|
|
|
459
|
+
def _valid_composite_container_indices(
|
|
460
|
+
self, container_properties_by_id: dict[tuple[ContainerEntity, str], list[tuple[int, PhysicalProperty]]]
|
|
461
|
+
) -> IssueList:
|
|
462
|
+
"""Validate that the indices on the container properties are valid."""
|
|
463
|
+
index_properties_by_container_index: dict[tuple[ContainerEntity, str], list[_ContainerPropertyIndex]] = (
|
|
464
|
+
defaultdict(list)
|
|
465
|
+
)
|
|
466
|
+
for (container, _), properties in container_properties_by_id.items():
|
|
467
|
+
for row_no, prop in properties:
|
|
468
|
+
for index in prop.index or []:
|
|
469
|
+
index_properties_by_container_index[(container, index.suffix)].append(
|
|
470
|
+
_ContainerPropertyIndex(row_no, prop, index)
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
properties_sheet_info = self._read_info_by_spreadsheet.get("Properties")
|
|
474
|
+
errors = IssueList()
|
|
475
|
+
for (container, _), index_properties in index_properties_by_container_index.items():
|
|
476
|
+
if len(index_properties) <= 1:
|
|
477
|
+
# If there is only one property in the index, this is already validated in the field_validator
|
|
478
|
+
# of the PhysicalProperty class. This validation is only for composite indices.
|
|
479
|
+
continue
|
|
480
|
+
container_id = container.as_id()
|
|
481
|
+
row_numbers = tuple([index_prop.location for index_prop in index_properties])
|
|
482
|
+
if properties_sheet_info:
|
|
483
|
+
row_numbers = tuple([properties_sheet_info.adjusted_row_number(row_no) for row_no in row_numbers])
|
|
484
|
+
|
|
485
|
+
if order_missing_error := self._validate_container_indices_has_order(
|
|
486
|
+
index_properties, row_numbers, container_id
|
|
487
|
+
):
|
|
488
|
+
errors.append(order_missing_error)
|
|
489
|
+
same_order_errors = self._validate_container_indices_same_order(index_properties, row_numbers, container_id)
|
|
490
|
+
errors.extend(same_order_errors)
|
|
491
|
+
return errors
|
|
492
|
+
|
|
493
|
+
@staticmethod
|
|
494
|
+
def _validate_container_indices_has_order(
|
|
495
|
+
index_properties: list[_ContainerPropertyIndex], row_numbers: tuple[int, ...], container_id: dm.ContainerId
|
|
496
|
+
) -> PropertyInvalidDefinitionError | None:
|
|
497
|
+
property_names: list[str] = []
|
|
498
|
+
indices: list[ContainerIndexEntity] = []
|
|
499
|
+
for prop_index in index_properties:
|
|
500
|
+
if prop_index.index.order is None:
|
|
501
|
+
property_names.append(prop_index.property_.view_property)
|
|
502
|
+
indices.append(prop_index.index)
|
|
503
|
+
|
|
504
|
+
if not property_names:
|
|
505
|
+
return None
|
|
506
|
+
|
|
507
|
+
if len(set(property_names)) == 1:
|
|
508
|
+
# If this is the same property, this is not a composite index, but a poorly defined single property
|
|
509
|
+
# index. This will be caught by the PropertyDefinitionDuplicatedError.
|
|
510
|
+
return None
|
|
511
|
+
|
|
512
|
+
properties_str = humanize_collection(property_names)
|
|
513
|
+
fixed_indices = [str(index.model_copy(update={"order": no})) for no, index in enumerate(indices, 1)]
|
|
514
|
+
message = (
|
|
515
|
+
"You must specify the order when using a composite index. "
|
|
516
|
+
f"For example {humanize_collection(fixed_indices)}."
|
|
517
|
+
)
|
|
518
|
+
return PropertyInvalidDefinitionError(
|
|
519
|
+
container_id,
|
|
520
|
+
"container",
|
|
521
|
+
properties_str,
|
|
522
|
+
message,
|
|
523
|
+
row_numbers,
|
|
524
|
+
"rows",
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
@staticmethod
|
|
528
|
+
def _validate_container_indices_same_order(
|
|
529
|
+
index_properties: list[_ContainerPropertyIndex], row_numbers: tuple[int, ...], container_id: dm.ContainerId
|
|
530
|
+
) -> list[PropertyInvalidDefinitionError]:
|
|
531
|
+
"""Checks whether there are multiple properties with the same order in a composite index."""
|
|
532
|
+
properties_by_order: dict[int, list[tuple[int, PhysicalProperty]]] = defaultdict(list)
|
|
533
|
+
for index_prop in index_properties:
|
|
534
|
+
if index_prop.index.order is not None:
|
|
535
|
+
properties_by_order[index_prop.index.order].append((index_prop.location, index_prop.property_))
|
|
536
|
+
same_order_errors: list[PropertyInvalidDefinitionError] = []
|
|
537
|
+
for order, props in properties_by_order.items():
|
|
538
|
+
if len(props) > 1:
|
|
539
|
+
properties_str = humanize_collection([prop.view_property for _, prop in props])
|
|
540
|
+
message = (
|
|
541
|
+
"You cannot have multiple properties with the same order in a composite index. "
|
|
542
|
+
f"Got order={order} for all composite properties."
|
|
543
|
+
"Please ensure that each property has an unique order."
|
|
544
|
+
)
|
|
545
|
+
same_order_errors.append(
|
|
546
|
+
PropertyInvalidDefinitionError(
|
|
547
|
+
container_id,
|
|
548
|
+
"container",
|
|
549
|
+
properties_str,
|
|
550
|
+
message,
|
|
551
|
+
row_numbers,
|
|
552
|
+
"rows",
|
|
553
|
+
)
|
|
554
|
+
)
|
|
555
|
+
return same_order_errors
|
|
556
|
+
|
|
425
557
|
@staticmethod
|
|
426
558
|
def _containers_are_proper_size(dms_schema: DMSSchema) -> IssueList:
|
|
427
559
|
errors = IssueList()
|
|
@@ -32,6 +32,7 @@ from cognite.neat.core._data_model.models._types import (
|
|
|
32
32
|
from cognite.neat.core._data_model.models.data_types import DataType
|
|
33
33
|
from cognite.neat.core._data_model.models.entities import (
|
|
34
34
|
ConceptualEntity,
|
|
35
|
+
ContainerIndexEntity,
|
|
35
36
|
DMSNodeEntity,
|
|
36
37
|
EdgeEntity,
|
|
37
38
|
HasDataFilter,
|
|
@@ -40,12 +41,13 @@ from cognite.neat.core._data_model.models.entities import (
|
|
|
40
41
|
PhysicalUnknownEntity,
|
|
41
42
|
RawFilter,
|
|
42
43
|
ReverseConnectionEntity,
|
|
44
|
+
Undefined,
|
|
43
45
|
ViewEntity,
|
|
44
46
|
ViewEntityList,
|
|
45
47
|
)
|
|
46
48
|
from cognite.neat.core._data_model.models.entities._types import ContainerEntityList, ContainerIndexListType
|
|
47
49
|
from cognite.neat.core._issues.errors import NeatValueError
|
|
48
|
-
from cognite.neat.core._issues.warnings
|
|
50
|
+
from cognite.neat.core._issues.warnings import NeatValueWarning, PropertyDefinitionWarning
|
|
49
51
|
|
|
50
52
|
if TYPE_CHECKING:
|
|
51
53
|
from cognite.neat.core._data_model.models import ConceptualDataModel
|
|
@@ -257,6 +259,53 @@ class PhysicalProperty(SheetRow):
|
|
|
257
259
|
)
|
|
258
260
|
return value
|
|
259
261
|
|
|
262
|
+
@field_validator("index", mode="after")
|
|
263
|
+
@classmethod
|
|
264
|
+
def index_set_correctly(cls, value: list[ContainerIndexEntity] | None, info: ValidationInfo) -> Any:
|
|
265
|
+
if value is None:
|
|
266
|
+
return value
|
|
267
|
+
try:
|
|
268
|
+
container = str(info.data["container"])
|
|
269
|
+
container_property = str(info.data["container_property"])
|
|
270
|
+
except KeyError:
|
|
271
|
+
raise ValueError("Container and container property must be set to use indexes") from None
|
|
272
|
+
max_count = info.data.get("max_count")
|
|
273
|
+
is_list = (
|
|
274
|
+
max_count is not None and (isinstance(max_count, int | float) and max_count > 1)
|
|
275
|
+
) or max_count is float("inf")
|
|
276
|
+
for index in value:
|
|
277
|
+
if index.prefix is Undefined:
|
|
278
|
+
message = f"The type of index is not defined. Please set 'inverted:{index!s}' or 'btree:{index!s}'."
|
|
279
|
+
warnings.warn(
|
|
280
|
+
PropertyDefinitionWarning(container, "container property", container_property, message),
|
|
281
|
+
stacklevel=2,
|
|
282
|
+
)
|
|
283
|
+
elif index.prefix == "inverted" and not is_list:
|
|
284
|
+
message = (
|
|
285
|
+
"It is not recommended to use inverted index on non-list properties. "
|
|
286
|
+
"Please consider using btree index instead."
|
|
287
|
+
)
|
|
288
|
+
warnings.warn(
|
|
289
|
+
PropertyDefinitionWarning(container, "container property", container_property, message),
|
|
290
|
+
stacklevel=2,
|
|
291
|
+
)
|
|
292
|
+
elif index.prefix == "btree" and is_list:
|
|
293
|
+
message = (
|
|
294
|
+
"It is not recommended to use btree index on list properties. "
|
|
295
|
+
"Please consider using inverted index instead."
|
|
296
|
+
)
|
|
297
|
+
warnings.warn(
|
|
298
|
+
PropertyDefinitionWarning(container, "container property", container_property, message),
|
|
299
|
+
stacklevel=2,
|
|
300
|
+
)
|
|
301
|
+
if index.prefix == "inverted" and (index.cursorable is not None or index.by_space is not None):
|
|
302
|
+
message = "Cursorable and bySpace are not supported for inverted indexes. These will be ignored."
|
|
303
|
+
warnings.warn(
|
|
304
|
+
PropertyDefinitionWarning(container, "container property", container_property, message),
|
|
305
|
+
stacklevel=2,
|
|
306
|
+
)
|
|
307
|
+
return value
|
|
308
|
+
|
|
260
309
|
@field_serializer("value_type", when_used="always")
|
|
261
310
|
def as_dms_type(self, value_type: DataType | EdgeEntity | ViewEntity, info: SerializationInfo) -> str:
|
|
262
311
|
if isinstance(value_type, DataType):
|
|
@@ -124,7 +124,7 @@ class NeatIssue:
|
|
|
124
124
|
if isinstance(value, str | int | bool | float):
|
|
125
125
|
return value
|
|
126
126
|
elif isinstance(value, frozenset):
|
|
127
|
-
return [cls._dump_value(item) for item in value]
|
|
127
|
+
return [cls._dump_value(item) for item in sorted(value)]
|
|
128
128
|
elif isinstance(value, Path):
|
|
129
129
|
return value.as_posix()
|
|
130
130
|
elif isinstance(value, tuple):
|
|
@@ -16,6 +16,7 @@ from ._general import NeatImportError, NeatTypeError, NeatValueError, RegexViola
|
|
|
16
16
|
from ._properties import (
|
|
17
17
|
PropertyDefinitionDuplicatedError,
|
|
18
18
|
PropertyDefinitionError,
|
|
19
|
+
PropertyInvalidDefinitionError,
|
|
19
20
|
PropertyMappingDuplicatedError,
|
|
20
21
|
PropertyNotFoundError,
|
|
21
22
|
PropertyTypeNotSupportedError,
|
|
@@ -65,6 +66,7 @@ __all__ = [
|
|
|
65
66
|
"OxigraphStorageLockedError",
|
|
66
67
|
"PropertyDefinitionDuplicatedError",
|
|
67
68
|
"PropertyDefinitionError",
|
|
69
|
+
"PropertyInvalidDefinitionError",
|
|
68
70
|
"PropertyMappingDuplicatedError",
|
|
69
71
|
"PropertyNotFoundError",
|
|
70
72
|
"PropertyTypeNotSupportedError",
|
|
@@ -60,6 +60,17 @@ class PropertyDefinitionDuplicatedError(PropertyError[T_Identifier]):
|
|
|
60
60
|
location_name: str | None = None
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
@dataclass(unsafe_hash=True)
|
|
64
|
+
class PropertyInvalidDefinitionError(PropertyError[T_Identifier]):
|
|
65
|
+
"""The {resource_type} with identifier {identifier} has an invalid definition of {property_name}. {reason}"""
|
|
66
|
+
|
|
67
|
+
extra = "in locations {locations} with name {location_name}"
|
|
68
|
+
|
|
69
|
+
reason: str
|
|
70
|
+
locations: tuple[str | int, ...] | None = None
|
|
71
|
+
location_name: str | None = None
|
|
72
|
+
|
|
73
|
+
|
|
63
74
|
@dataclass(unsafe_hash=True)
|
|
64
75
|
class PropertyMappingDuplicatedError(PropertyError[T_Identifier], Generic[T_Identifier, T_ReferenceIdentifier]):
|
|
65
76
|
"""The {resource_type} with identifier {identifier}.{property_name} is mapped to by: {mappings}. Ensure
|
|
@@ -34,6 +34,7 @@ from ._models import (
|
|
|
34
34
|
from ._properties import (
|
|
35
35
|
PropertyDataTypeConversionWarning,
|
|
36
36
|
PropertyDefinitionDuplicatedWarning,
|
|
37
|
+
PropertyDefinitionWarning,
|
|
37
38
|
PropertyDirectRelationLimitWarning,
|
|
38
39
|
PropertyMultipleValueWarning,
|
|
39
40
|
PropertyNotFoundWarning,
|
|
@@ -72,6 +73,7 @@ __all__ = [
|
|
|
72
73
|
"PrincipleSolutionBuildsOnEnterpriseWarning",
|
|
73
74
|
"PropertyDataTypeConversionWarning",
|
|
74
75
|
"PropertyDefinitionDuplicatedWarning",
|
|
76
|
+
"PropertyDefinitionWarning",
|
|
75
77
|
"PropertyDirectRelationLimitWarning",
|
|
76
78
|
"PropertyMultipleValueWarning",
|
|
77
79
|
"PropertyNotFoundWarning",
|
|
@@ -90,6 +90,17 @@ class PropertyMultipleValueWarning(PropertyWarning[T_Identifier]):
|
|
|
90
90
|
value: str
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
@dataclass(unsafe_hash=True)
|
|
94
|
+
class PropertyDefinitionWarning(PropertyWarning[T_Identifier]):
|
|
95
|
+
"""The {resource_type} with identifier {identifier} property {property_name}: {reason}"""
|
|
96
|
+
|
|
97
|
+
extra = "in locations {locations} with name {location_name}"
|
|
98
|
+
|
|
99
|
+
reason: str
|
|
100
|
+
locations: tuple[str | int, ...] | None = None
|
|
101
|
+
location_name: str | None = None
|
|
102
|
+
|
|
103
|
+
|
|
93
104
|
@dataclass(unsafe_hash=True)
|
|
94
105
|
class ReversedConnectionNotFeasibleWarning(PropertyWarning[T_Identifier]):
|
|
95
106
|
"""The {resource_type} {identifier}.{property_name} cannot be created: {reason}"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cognite-neat
|
|
3
|
-
Version: 0.123.
|
|
3
|
+
Version: 0.123.10
|
|
4
4
|
Summary: Knowledge graph transformation
|
|
5
5
|
Project-URL: Documentation, https://cognite-neat.readthedocs-hosted.com/
|
|
6
6
|
Project-URL: Homepage, https://cognite-neat.readthedocs-hosted.com/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
cognite/neat/__init__.py,sha256=12StS1dzH9_MElqxGvLWrNsxCJl9Hv8A2a9D0E5OD_U,193
|
|
2
|
-
cognite/neat/_version.py,sha256=
|
|
2
|
+
cognite/neat/_version.py,sha256=1gIfsiIXBpIQcL009UOK01UgGBkk1zRJKTokYRpZEmY,47
|
|
3
3
|
cognite/neat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
cognite/neat/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
cognite/neat/core/_config.py,sha256=WT1BS8uADcFvGoUYOOfwFOVq_VBl472TisdoA3wLick,280
|
|
@@ -19,7 +19,7 @@ cognite/neat/core/_client/data_classes/neat_sequence.py,sha256=QZWSfWnwk6KlYJvsI
|
|
|
19
19
|
cognite/neat/core/_client/data_classes/schema.py,sha256=SpkBGbC2SUJG38Ixf1vYJINI66i_OZaT03q4XKRtK54,25067
|
|
20
20
|
cognite/neat/core/_client/data_classes/statistics.py,sha256=GU-u41cOTig0Y5pYhW5KqzCsuAUIX9tOmdizMEveYuw,4487
|
|
21
21
|
cognite/neat/core/_data_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
cognite/neat/core/_data_model/_constants.py,sha256=
|
|
22
|
+
cognite/neat/core/_data_model/_constants.py,sha256=ssiOprhd4bamglQnLTNjmqYn9mCBW-VOUbn08qDBbsM,5857
|
|
23
23
|
cognite/neat/core/_data_model/_shared.py,sha256=gLEEMofI9prZLRNjHpwQe0uX9WoKd5qUt5pT1i_KAYo,2072
|
|
24
24
|
cognite/neat/core/_data_model/analysis/__init__.py,sha256=v3hSfz7AEEqcmdjL71I09tP8Hl-gPZYOiDYMp_CW4vg,70
|
|
25
25
|
cognite/neat/core/_data_model/analysis/_base.py,sha256=baqgY-66zOUxw8s-PA1KGAOs2R1gJDAo2UWWc8LlHGU,24257
|
|
@@ -52,7 +52,7 @@ cognite/neat/core/_data_model/models/_types.py,sha256=70E8fiLdZkVF2sDUGPuDhzXNA5
|
|
|
52
52
|
cognite/neat/core/_data_model/models/data_types.py,sha256=uQ_u9KxCetLjxo-VtFzOXSxQuuf97Kg-9lfTTGzY6hc,10150
|
|
53
53
|
cognite/neat/core/_data_model/models/conceptual/__init__.py,sha256=9A6myEV8s0-LqdXejaljqPj8S0pIpUL75rNdRDZzyR8,585
|
|
54
54
|
cognite/neat/core/_data_model/models/conceptual/_unverified.py,sha256=apisgtXMb50dOs7rxZ-jcCW4JqxCdAWGtsYtRe3ssfs,6282
|
|
55
|
-
cognite/neat/core/_data_model/models/conceptual/_validation.py,sha256=
|
|
55
|
+
cognite/neat/core/_data_model/models/conceptual/_validation.py,sha256=ywWFkxhQvDvB-NCIjWNv7-aOouBCz7HoxtJ0aC_b6BY,13034
|
|
56
56
|
cognite/neat/core/_data_model/models/conceptual/_verified.py,sha256=e5Qs7n1np4g6inHQwuLUk2rCwgLf129je54xLnzENpw,13659
|
|
57
57
|
cognite/neat/core/_data_model/models/entities/__init__.py,sha256=UsW-_6fwd-TW0WcnShPKf40h75l1elVn80VurUwRAic,1567
|
|
58
58
|
cognite/neat/core/_data_model/models/entities/_constants.py,sha256=GXRzVfArwxF3C67VCkzy0JWTZRkRJUYXBQaaecrqcWc,351
|
|
@@ -67,8 +67,8 @@ cognite/neat/core/_data_model/models/mapping/_classic2core.yaml,sha256=ei-nuivNW
|
|
|
67
67
|
cognite/neat/core/_data_model/models/physical/__init__.py,sha256=ONE_xLw1cxfw88rICG_RtbjCYUZm8yS2kBQ4Di3EGnA,987
|
|
68
68
|
cognite/neat/core/_data_model/models/physical/_exporter.py,sha256=DPOytV-sIzpGJtfDEfi7G4RWnSCVNRLWe1KzY26ewmc,30083
|
|
69
69
|
cognite/neat/core/_data_model/models/physical/_unverified.py,sha256=VyI-JULAu6kHJygUclDPH1JYjhf_XcO58tI9BkXORC0,18430
|
|
70
|
-
cognite/neat/core/_data_model/models/physical/_validation.py,sha256=
|
|
71
|
-
cognite/neat/core/_data_model/models/physical/_verified.py,sha256=
|
|
70
|
+
cognite/neat/core/_data_model/models/physical/_validation.py,sha256=icgNNmvc60lIxI91NGGL5Bs7rR9evNtEubYYMMeKBVg,39529
|
|
71
|
+
cognite/neat/core/_data_model/models/physical/_verified.py,sha256=4_7XUj6-x74DhL8qe-duXhlNnq6ANmShB7UpICjbQW4,26783
|
|
72
72
|
cognite/neat/core/_data_model/transformers/__init__.py,sha256=_FPmPh0kA68SXR4arKKNmtWQ8B2-wSwWQeGAWnjoJAQ,1788
|
|
73
73
|
cognite/neat/core/_data_model/transformers/_base.py,sha256=7adUBJgDkXgRq_h7l1q2VsLQo3lE7-xmzmHdcF4QHq8,3133
|
|
74
74
|
cognite/neat/core/_data_model/transformers/_converters.py,sha256=OazYC7DgAXXEvxdiaPfJSe2ZNkYn2mRqWhtvtvWK59g,111575
|
|
@@ -118,21 +118,21 @@ cognite/neat/core/_instances/transformers/_prune_graph.py,sha256=fWE73BndkEB7qfM
|
|
|
118
118
|
cognite/neat/core/_instances/transformers/_rdfpath.py,sha256=4PIVpjlng59oTjoToS683XU0WgtKdEOf8zEhXCD94-I,3161
|
|
119
119
|
cognite/neat/core/_instances/transformers/_value_type.py,sha256=-d18yefiGrx8CaVNLgJe0dF0zsMxtCQxlD2q2ZFGJ8U,15820
|
|
120
120
|
cognite/neat/core/_issues/__init__.py,sha256=NQ-PN3fqp-hBPlpG2AZEND4cDn3_3UXAPfhLNtF5mtc,457
|
|
121
|
-
cognite/neat/core/_issues/_base.py,sha256=
|
|
121
|
+
cognite/neat/core/_issues/_base.py,sha256=Wfu0IxFEm-zaS631iMG_TgW_sLV3z0yn5x0IpFNS_hM,11808
|
|
122
122
|
cognite/neat/core/_issues/_contextmanagers.py,sha256=5-QXVmfplt4S_k2csrQ2xuezOOuE5_FxSA9GVGVG1s4,1582
|
|
123
123
|
cognite/neat/core/_issues/_factory.py,sha256=ifEzHZcvPyO0ZGJo8T8CE20F5L4yRzrrGPxl9d87oIs,2829
|
|
124
124
|
cognite/neat/core/_issues/formatters.py,sha256=k2h_6wHW0ve52gXeuRoEcGwrxqqSe5sYFa_HycPiqW8,3323
|
|
125
|
-
cognite/neat/core/_issues/errors/__init__.py,sha256=
|
|
125
|
+
cognite/neat/core/_issues/errors/__init__.py,sha256=YkJeNnB1FDhYYTUbsb6iIm2rzI7usDYdjQDb4qrfFR4,2492
|
|
126
126
|
cognite/neat/core/_issues/errors/_external.py,sha256=AaKwO5-AvX01d7Hd83vqYl1qNmMtgsmShmvyH8ioZAM,2354
|
|
127
127
|
cognite/neat/core/_issues/errors/_general.py,sha256=QEgTp_bvzGjmpRtr09Lj_SBeD9IVdql5_JmP02P7PfM,1391
|
|
128
|
-
cognite/neat/core/_issues/errors/_properties.py,sha256=
|
|
128
|
+
cognite/neat/core/_issues/errors/_properties.py,sha256=ZR2_j-TkxT8Zn5NGMNNOuKQ_bKeciaMOGZkRKg1YCvw,2924
|
|
129
129
|
cognite/neat/core/_issues/errors/_resources.py,sha256=lBK65tJZMhV3z3_xi8zJeo7Nt_agXsOklH_RPKQu28s,4002
|
|
130
130
|
cognite/neat/core/_issues/errors/_wrapper.py,sha256=clhuSwUuHy-FQXQopFIQRY8c_NZM5u-QB9ncoc6Hrbo,2320
|
|
131
|
-
cognite/neat/core/_issues/warnings/__init__.py,sha256=
|
|
131
|
+
cognite/neat/core/_issues/warnings/__init__.py,sha256=lzNZrguzwXyifehsCilAXa5UL94DWHIeO-slyC-EYZc,3165
|
|
132
132
|
cognite/neat/core/_issues/warnings/_external.py,sha256=w-1R7ea6DXTIWqwlwMMjY0YxKDMSJ8gKAbp_nIIM1AI,1324
|
|
133
133
|
cognite/neat/core/_issues/warnings/_general.py,sha256=_6dAFaMz-LIv7GsBBIBq2d-kmbuxVXKvU4jZeb7tjAo,972
|
|
134
134
|
cognite/neat/core/_issues/warnings/_models.py,sha256=0uqJTR8sXiobIqqh05sRc8-QdMuV6h_4ZDm2RfxpEew,4396
|
|
135
|
-
cognite/neat/core/_issues/warnings/_properties.py,sha256=
|
|
135
|
+
cognite/neat/core/_issues/warnings/_properties.py,sha256=I3vqc1aL-ce_FRQNgQQy34RW7kQxcjbwhZIIVtGVmg8,3807
|
|
136
136
|
cognite/neat/core/_issues/warnings/_resources.py,sha256=_iPRq0pRMmRu3LFjqZTaG3OqOzw4f8-Vc9G4Im__FHc,3578
|
|
137
137
|
cognite/neat/core/_issues/warnings/user_modeling.py,sha256=Qn_S8TLw7MMYQaJcZBScJA48kz_PrTWz0NaepSR70Fk,4144
|
|
138
138
|
cognite/neat/core/_store/__init__.py,sha256=wpsF8xjIQ5V21NOh45XQV813n_EzgyPOt0VVinYjnDI,140
|
|
@@ -186,7 +186,7 @@ cognite/neat/session/engine/__init__.py,sha256=D3MxUorEs6-NtgoICqtZ8PISQrjrr4dvc
|
|
|
186
186
|
cognite/neat/session/engine/_import.py,sha256=1QxA2_EK613lXYAHKQbZyw2yjo5P9XuiX4Z6_6-WMNQ,169
|
|
187
187
|
cognite/neat/session/engine/_interface.py,sha256=3W-cYr493c_mW3P5O6MKN1xEQg3cA7NHR_ev3zdF9Vk,533
|
|
188
188
|
cognite/neat/session/engine/_load.py,sha256=g52uYakQM03VqHt_RDHtpHso1-mFFifH5M4T2ScuH8A,5198
|
|
189
|
-
cognite_neat-0.123.
|
|
190
|
-
cognite_neat-0.123.
|
|
191
|
-
cognite_neat-0.123.
|
|
192
|
-
cognite_neat-0.123.
|
|
189
|
+
cognite_neat-0.123.10.dist-info/METADATA,sha256=8GWYEXewakZw_c6yK9-zMHt5NpzeoPBFyjliGHAAGn4,9172
|
|
190
|
+
cognite_neat-0.123.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
191
|
+
cognite_neat-0.123.10.dist-info/licenses/LICENSE,sha256=W8VmvFia4WHa3Gqxq1Ygrq85McUNqIGDVgtdvzT-XqA,11351
|
|
192
|
+
cognite_neat-0.123.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|