industrial-model 0.1.16__py3-none-any.whl → 0.1.18__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.
@@ -1,5 +1,6 @@
1
1
  from collections import defaultdict
2
- from typing import Any, TypedDict
2
+ from enum import StrEnum
3
+ from typing import Any, Literal, TypedDict
3
4
 
4
5
  from cognite.client.data_classes.data_modeling import (
5
6
  Edge,
@@ -19,8 +20,15 @@ from industrial_model.models import EdgeContainer
19
20
  from .view_mapper import ViewMapper
20
21
 
21
22
 
23
+ class ConnectionTypeEnum(StrEnum):
24
+ DIRECT_RELATION = "DirectRelation"
25
+ REVERSE_DIRECT_RELATION = "ReverseDirectRelation"
26
+ EDGE = "Edge"
27
+
28
+
22
29
  class _PropertyMapping(TypedDict):
23
30
  is_list: bool
31
+ connection_type: ConnectionTypeEnum
24
32
  nodes: dict[tuple[str, str], list[Node]]
25
33
  edges: dict[tuple[str, str], list[Edge]]
26
34
 
@@ -92,16 +100,26 @@ class QueryResultMapper:
92
100
  for mapping_key, mapping_value in mappings.items():
93
101
  element = properties.get(mapping_key)
94
102
 
103
+ mapping_nodes = mapping_value.get("nodes", {})
104
+ mapping_edges = mapping_value.get("edges", {})
105
+ is_list = mapping_value.get("is_list", False)
106
+ connection_type = mapping_value.get(
107
+ "connection_type",
108
+ ConnectionTypeEnum.DIRECT_RELATION,
109
+ )
110
+
111
+ if (
112
+ element is None
113
+ and connection_type == ConnectionTypeEnum.DIRECT_RELATION
114
+ ):
115
+ continue
116
+
95
117
  element_key: tuple[str, str] = (
96
118
  (element.get("space", ""), element.get("externalId", ""))
97
119
  if isinstance(element, dict)
98
120
  else (node.space, node.external_id)
99
121
  )
100
122
 
101
- mapping_nodes = mapping_value.get("nodes", {})
102
- mapping_edges = mapping_value.get("edges", {})
103
- is_list = mapping_value.get("is_list", False)
104
-
105
123
  node_entries = mapping_nodes.get(element_key)
106
124
  if not node_entries:
107
125
  continue
@@ -116,6 +134,7 @@ class QueryResultMapper:
116
134
  edge_entries
117
135
  )
118
136
  properties["_edges"] = edges_mapping
137
+
119
138
  node.properties[view_id] = properties
120
139
 
121
140
  result[node_id].append(node)
@@ -136,6 +155,9 @@ class QueryResultMapper:
136
155
  nodes: dict[tuple[str, str], list[Node]] | None = None
137
156
  edges: dict[tuple[str, str], list[Edge]] | None = None
138
157
  is_list = False
158
+ connection_type: ConnectionTypeEnum = (
159
+ ConnectionTypeEnum.DIRECT_RELATION
160
+ )
139
161
 
140
162
  if isinstance(property, MappedProperty) and property.source:
141
163
  nodes = self._map_node_property(
@@ -144,6 +166,7 @@ class QueryResultMapper:
144
166
  query_result,
145
167
  )
146
168
  is_list = False
169
+ connection_type = ConnectionTypeEnum.DIRECT_RELATION
147
170
  elif (
148
171
  isinstance(property, SingleReverseDirectRelation)
149
172
  and property.source
@@ -155,6 +178,7 @@ class QueryResultMapper:
155
178
  property.through.property,
156
179
  )
157
180
  is_list = False
181
+ connection_type = ConnectionTypeEnum.REVERSE_DIRECT_RELATION
158
182
  elif (
159
183
  isinstance(property, MultiReverseDirectRelation)
160
184
  and property.source
@@ -166,6 +190,7 @@ class QueryResultMapper:
166
190
  property.through.property,
167
191
  )
168
192
  is_list = True
193
+ connection_type = ConnectionTypeEnum.REVERSE_DIRECT_RELATION
169
194
 
170
195
  elif isinstance(property, EdgeConnection) and property.source:
171
196
  nodes, edges = self._map_edge_property(
@@ -175,10 +200,14 @@ class QueryResultMapper:
175
200
  property.direction,
176
201
  )
177
202
  is_list = True
203
+ connection_type = ConnectionTypeEnum.EDGE
178
204
 
179
205
  if nodes:
180
206
  mappings[property_name] = _PropertyMapping(
181
- is_list=is_list, nodes=nodes, edges=edges or {}
207
+ is_list=is_list,
208
+ connection_type=connection_type,
209
+ nodes=nodes,
210
+ edges=edges or {},
182
211
  )
183
212
 
184
213
  return mappings
@@ -101,5 +101,8 @@ class PaginatedResult(RootModel, Generic[TViewInstance]):
101
101
  has_next_page: bool
102
102
  next_cursor: str | None
103
103
 
104
+ def first_or_default(self) -> TViewInstance | None:
105
+ return self.data[0] if self.data else None
106
+
104
107
 
105
108
  ValidationMode = Literal["raiseOnError", "ignoreOnError"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: industrial-model
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Industrial Model ORM
5
5
  Author-email: Lucas Alves <lucasrosaalves@gmail.com>
6
6
  Classifier: Programming Language :: Python
@@ -9,7 +9,7 @@ industrial_model/cognite_adapters/filter_mapper.py,sha256=X2BVp305v1Wt00DTZEnCoo
9
9
  industrial_model/cognite_adapters/models.py,sha256=2j2IS01uPkQEp9WdVk8seYzEqGcDdWFnpzXhusHB2zk,945
10
10
  industrial_model/cognite_adapters/optimizer.py,sha256=BbbsA3r9ZKJt6mN1wVRZc046ov-vbml9_ESfurTNRUg,2477
11
11
  industrial_model/cognite_adapters/query_mapper.py,sha256=3fEcaLsGjLKIh-g1BbMcffQ6rp99JeCW555iJo8JW44,6260
12
- industrial_model/cognite_adapters/query_result_mapper.py,sha256=lsKz0wiqMOo54MVEw_YqLcHXa_HWYgAbSLnBbbdVupw,8451
12
+ industrial_model/cognite_adapters/query_result_mapper.py,sha256=e2W2QPDUusZh0cgpvIKF21_dP7QyZjLKrp_H_OQ4Ddk,9516
13
13
  industrial_model/cognite_adapters/sort_mapper.py,sha256=RJUAYlZGXoYzK0PwX63cibRF_L-MUq9g2ZsC2EeNIF4,696
14
14
  industrial_model/cognite_adapters/upsert_mapper.py,sha256=tWEiBJQeeNz1HDu0AoBIfCw_LL156Zg4h7ORKlZ__uw,4870
15
15
  industrial_model/cognite_adapters/utils.py,sha256=rztCtS10ZTQmXfBv0nLgDiQIMWemhdSFK-SwrbRjVxM,4792
@@ -19,13 +19,13 @@ industrial_model/engines/async_engine.py,sha256=XgDKCHh4gi2mPBknp7MM4mRsuA_224Ne
19
19
  industrial_model/engines/engine.py,sha256=DaA34P1aL_qvL691OG_-g_yCC-U2ZJr9tF32Pl5vpP4,3098
20
20
  industrial_model/models/__init__.py,sha256=AzJ0CyPK5PvUCX45FFtybl13tkukUvk2UAF_90s_LQ8,742
21
21
  industrial_model/models/base.py,sha256=iGhDjXqA5ULEQIFHtkMi7WYJl0nQq1wi8_zqOr-Ep78,1649
22
- industrial_model/models/entities.py,sha256=GZu-Y5ZalhXM8EHTzBe4hCKA2Dryk8J99p_FTVNX2jc,2709
22
+ industrial_model/models/entities.py,sha256=1ZmijxOXEAWocf3HTJ9a7ci5cJEjzA3hbt0QvVP8Gb8,2817
23
23
  industrial_model/models/schemas.py,sha256=-ZnDO-yJL2PR4QmsduzDsC-rjS7CZnqPS-wYAo65Mbo,4612
24
24
  industrial_model/queries/__init__.py,sha256=7aheTE5qs03rxWm9fmGWptbz_p9OIXXYD8if56cqs18,227
25
25
  industrial_model/queries/models.py,sha256=iiHQ7-cfg0nukEv5PoCx9QPF-w1gVSnoNbXBOK9Mzeo,1185
26
26
  industrial_model/queries/params.py,sha256=ehgCoR5n6E-tkEuoymZ2lkLcSzMaBAx_HnyJ7sWpqz0,964
27
27
  industrial_model/statements/__init__.py,sha256=15LI9POLUdh6i3Zw0Aek0fVFfcTj8P8ZEa1Cli3pgXQ,3095
28
28
  industrial_model/statements/expressions.py,sha256=Sar1cIvy3sYi7tkWJN3ylHlZ252oN2mZJpZ1TX9jN3s,4940
29
- industrial_model-0.1.16.dist-info/METADATA,sha256=5Bq6L2p-45gPQWKPZPPl1yFQ3JAqT8w9-IonyNnT844,6144
30
- industrial_model-0.1.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
- industrial_model-0.1.16.dist-info/RECORD,,
29
+ industrial_model-0.1.18.dist-info/METADATA,sha256=s9T_m788nocZAMzq-wbf1bTi9VLDW8vdCryL-DO4BtU,6144
30
+ industrial_model-0.1.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
+ industrial_model-0.1.18.dist-info/RECORD,,