industrial-model 0.1.31__py3-none-any.whl → 0.1.32__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.
@@ -2,7 +2,11 @@ from datetime import date, datetime
2
2
  from typing import Any
3
3
 
4
4
  import cognite.client.data_classes.filters as cdf_filters
5
- from cognite.client.data_classes.data_modeling import MappedProperty, View
5
+ from cognite.client.data_classes.data_modeling import (
6
+ EdgeConnection,
7
+ MappedProperty,
8
+ View,
9
+ )
6
10
 
7
11
  from industrial_model.cognite_adapters.utils import get_property_ref
8
12
  from industrial_model.models.entities import InstanceId
@@ -11,6 +15,7 @@ from industrial_model.statements import (
11
15
  Expression,
12
16
  LeafExpression,
13
17
  )
18
+ from industrial_model.statements.expressions import Column
14
19
  from industrial_model.utils import datetime_to_ms_iso_timestamp
15
20
 
16
21
  from .view_mapper import ViewMapper
@@ -26,15 +31,37 @@ class FilterMapper:
26
31
  result: list[cdf_filters.Filter] = []
27
32
  for expression in expressions:
28
33
  if isinstance(expression, BoolExpression):
29
- result.append(self.to_cdf_filter_bool(expression, root_view))
34
+ result.append(self._to_cdf_filter_bool(expression, root_view))
30
35
  elif isinstance(expression, LeafExpression):
31
- result.append(self.to_cdf_filter_leaf(expression, root_view))
36
+ result.append(self._to_cdf_filter_leaf(expression, root_view))
32
37
  else:
33
38
  cls_name = expression.__class__.__name__
34
39
  raise ValueError(f"Expression not implemented {cls_name}")
35
40
  return result
36
41
 
37
- def to_cdf_filter_bool(
42
+ def map_edges(
43
+ self,
44
+ edges_expressions: list[tuple[Column, list[Expression]]],
45
+ root_view: View,
46
+ nested_separator: str,
47
+ ) -> dict[str, list[cdf_filters.Filter]]:
48
+ result_dict: dict[str, list[cdf_filters.Filter]] = {}
49
+
50
+ for column, expressions in edges_expressions:
51
+ view_property = root_view.properties.get(column.property)
52
+ if not isinstance(view_property, EdgeConnection):
53
+ raise ValueError(f"Property {column.property} is not an edge")
54
+
55
+ filters = self.map(
56
+ expressions,
57
+ self._view_mapper.get_view(view_property.source.external_id),
58
+ )
59
+ result_key = root_view.external_id + nested_separator + column.property
60
+ result_dict.setdefault(result_key, []).extend(filters)
61
+
62
+ return result_dict
63
+
64
+ def _to_cdf_filter_bool(
38
65
  self, expression: BoolExpression, root_view: View
39
66
  ) -> cdf_filters.Filter:
40
67
  arguments = self.map(expression.filters, root_view)
@@ -48,7 +75,7 @@ class FilterMapper:
48
75
 
49
76
  raise NotImplementedError(f"Operator {self.operator} not implemented")
50
77
 
51
- def to_cdf_filter_leaf(
78
+ def _to_cdf_filter_leaf(
52
79
  self,
53
80
  expression: LeafExpression,
54
81
  root_view: View,
@@ -58,8 +58,12 @@ class QueryMapper:
58
58
 
59
59
  relations = get_schema_properties(statement.entity, NESTED_SEP, root_node)
60
60
 
61
+ edge_filters = self._filter_mapper.map_edges(
62
+ statement.where_edge_clauses, root_view, NESTED_SEP
63
+ )
64
+
61
65
  properties = self._include_statements(
62
- root_node, root_view, relations, with_, select_
66
+ root_node, root_view, relations, edge_filters, with_, select_
63
67
  )
64
68
 
65
69
  select_[root_node] = self._get_select(root_view_id, properties)
@@ -80,6 +84,7 @@ class QueryMapper:
80
84
  key: str,
81
85
  view: View,
82
86
  relations_to_include: list[str] | None,
87
+ edge_filters: dict[str, list[filters.Filter]],
83
88
  with_: dict[str, ResultSetExpression],
84
89
  select_: dict[str, Select],
85
90
  ) -> list[str]:
@@ -101,6 +106,7 @@ class QueryMapper:
101
106
  property_key,
102
107
  self._view_mapper.get_view(property.source.external_id),
103
108
  relations_to_include,
109
+ edge_filters,
104
110
  with_,
105
111
  select_,
106
112
  )
@@ -121,6 +127,7 @@ class QueryMapper:
121
127
  property_key,
122
128
  self._view_mapper.get_view(property.source.external_id),
123
129
  relations_to_include,
130
+ edge_filters,
124
131
  with_,
125
132
  select_,
126
133
  )
@@ -139,10 +146,16 @@ class QueryMapper:
139
146
  elif isinstance(property, EdgeConnection) and property.source:
140
147
  edge_property_key = f"{property_key}{NESTED_SEP}{EDGE_MARKER}"
141
148
 
149
+ edge_filter = edge_filters.get(property_key)
150
+
142
151
  with_[edge_property_key] = EdgeResultSetExpression(
143
152
  from_=key,
144
153
  max_distance=1,
145
- filter=filters.Equals(["edge", "type"], property.type.dump()),
154
+ filter=filters.Equals(
155
+ ["edge", "type"],
156
+ property.type.dump(),
157
+ ),
158
+ node_filter=filters.And(*edge_filter) if edge_filter else None,
146
159
  direction=property.direction,
147
160
  limit=MAX_LIMIT,
148
161
  )
@@ -157,6 +170,7 @@ class QueryMapper:
157
170
  property_key,
158
171
  self._view_mapper.get_view(property.source.external_id),
159
172
  relations_to_include,
173
+ edge_filters,
160
174
  with_,
161
175
  select_,
162
176
  )
@@ -16,7 +16,7 @@ from industrial_model.statements import Column
16
16
  from .base import DBModelMetaclass, RootModel
17
17
 
18
18
 
19
- class InstanceId(RootModel):
19
+ class InstanceId(RootModel, metaclass=DBModelMetaclass):
20
20
  external_id: str
21
21
  space: str
22
22
 
@@ -51,7 +51,7 @@ class ViewInstanceConfig(TypedDict, total=False):
51
51
  view_code: str | None
52
52
 
53
53
 
54
- class ViewInstance(InstanceId, metaclass=DBModelMetaclass):
54
+ class ViewInstance(InstanceId):
55
55
  view_config: ClassVar[ViewInstanceConfig] = ViewInstanceConfig()
56
56
 
57
57
  _edges: dict[str, list[EdgeContainer]] = PrivateAttr(default_factory=dict)
@@ -60,11 +60,33 @@ class BaseStatement(Generic[T]):
60
60
  @dataclass
61
61
  class Statement(BaseStatement[T]):
62
62
  cursor_: str | None = field(init=False, default=None)
63
+ where_edge_clauses: list[tuple[Column, list[Expression]]] = field(
64
+ init=False, default_factory=list
65
+ )
63
66
 
64
67
  def cursor(self, cursor: str | None) -> Self:
65
68
  self.cursor_ = cursor
66
69
  return self
67
70
 
71
+ def where_edge(
72
+ self, property: str | Column | Any, *expressions: bool | Expression
73
+ ) -> Self:
74
+ if not expressions:
75
+ return self
76
+
77
+ expressions_: list[Expression] = []
78
+ for expression in expressions:
79
+ assert isinstance(expression, Expression)
80
+ expressions_.append(expression)
81
+
82
+ self.where_edge_clauses.append(
83
+ (
84
+ _create_column(property),
85
+ expressions_,
86
+ )
87
+ )
88
+ return self
89
+
68
90
 
69
91
  @dataclass
70
92
  class SearchStatement(BaseStatement[T]):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: industrial-model
3
- Version: 0.1.31
3
+ Version: 0.1.32
4
4
  Summary: Industrial Model ORM
5
5
  Author-email: Lucas Alves <lucasrosaalves@gmail.com>
6
6
  Classifier: Programming Language :: Python
@@ -5,10 +5,10 @@ industrial_model/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  industrial_model/utils.py,sha256=oh4AxwxXaWgIC2uolkCbvkgo0ququHB6yAPVIXy45Ts,663
6
6
  industrial_model/cognite_adapters/__init__.py,sha256=cKPW5y-wWiyWYLPDaNjhqc5zdsgdLc40vunIlz2Debg,6246
7
7
  industrial_model/cognite_adapters/aggregation_mapper.py,sha256=qglWUnyhgSPG005HzIRyjYkt9V2WKsab5y4ruwuKLcA,2503
8
- industrial_model/cognite_adapters/filter_mapper.py,sha256=R_OX8JOM33vzBVFvfo0iDmSJl5rhGjsTBLyKDoesHO0,4349
8
+ industrial_model/cognite_adapters/filter_mapper.py,sha256=mo-SmUzeNYPKdO8Ed_Kz02RWXMRqsZP7VVjKPWQtn4g,5308
9
9
  industrial_model/cognite_adapters/models.py,sha256=2j2IS01uPkQEp9WdVk8seYzEqGcDdWFnpzXhusHB2zk,945
10
10
  industrial_model/cognite_adapters/optimizer.py,sha256=EQfCe-4mSeXhYa2kcqJerPXYsCRgMJPA1AIf1o1KNH0,2415
11
- industrial_model/cognite_adapters/query_mapper.py,sha256=QdFVkfmL4tWcCy_oypOluT0Fo68obPk2RjBPvVA9mUs,5950
11
+ industrial_model/cognite_adapters/query_mapper.py,sha256=ui-FhF7ixsJU8jAFNotdZ8vfSKtnjzZYkvLNgMU27Jc,6467
12
12
  industrial_model/cognite_adapters/query_result_mapper.py,sha256=KaBqYr5l1t8sQMxEoX_F3J2prypKIPaDJxSzGF_fMB8,10203
13
13
  industrial_model/cognite_adapters/search_mapper.py,sha256=dh69Te8oiDIRPbEMTcof-ZJ4XD-xB5iiBHUR0UETzho,1504
14
14
  industrial_model/cognite_adapters/sort_mapper.py,sha256=RJUAYlZGXoYzK0PwX63cibRF_L-MUq9g2ZsC2EeNIF4,696
@@ -20,14 +20,14 @@ industrial_model/engines/async_engine.py,sha256=-sQv2vn93bBmTZOxY_C1r40YP7IMl1ND
20
20
  industrial_model/engines/engine.py,sha256=lECOpjN6fGvKt28b441isT_u4UNF3LeLiJH-zwHmkYw,3798
21
21
  industrial_model/models/__init__.py,sha256=AzJ0CyPK5PvUCX45FFtybl13tkukUvk2UAF_90s_LQ8,742
22
22
  industrial_model/models/base.py,sha256=iGhDjXqA5ULEQIFHtkMi7WYJl0nQq1wi8_zqOr-Ep78,1649
23
- industrial_model/models/entities.py,sha256=BC85P8THwvVmcNpYq2spJuFJtlK8Oegkmd0kx3CI_wU,4704
23
+ industrial_model/models/entities.py,sha256=XugtGFCJrHnxR4UX7FWFumB2tNZGB7mNjM4skznnmdQ,4704
24
24
  industrial_model/models/schemas.py,sha256=EoLK9GYdS-0DQ98myTP3wOU9YpWIJOfDSLOYZUy3xEY,4559
25
25
  industrial_model/queries/__init__.py,sha256=lA83zOxMRgBgkseWJgK9kCr1vD8D8iSWs9NGGRnoYKk,355
26
26
  industrial_model/queries/models.py,sha256=VK69c4L0b0miPrKvOQBB8A01SPxZXYThrquv6gw5OGY,2544
27
27
  industrial_model/queries/params.py,sha256=50qY5BO5onLsXorhcv-7qCKhJaMO94UzhKLCmZKY55s,1667
28
28
  industrial_model/queries/utils.py,sha256=uP6PLh9IVHDK6J8x444zHWPmyV4PkxdLO-PMc6qWItc,1505
29
- industrial_model/statements/__init__.py,sha256=rjLRo2KoazHQaOpmPkxbI3_Nm8NCkJxjpuqow6IZVSc,4221
29
+ industrial_model/statements/__init__.py,sha256=dNEFceuirobo3c9b8KB-3qgKihZ4yfnUj5U-1978eBM,4856
30
30
  industrial_model/statements/expressions.py,sha256=4ZZOcZroI5-4xRw4PXIRlufi0ARndE5zSbbxLDpR2Ec,4816
31
- industrial_model-0.1.31.dist-info/METADATA,sha256=BZq-MwEpDSndxkVUf5A6odc9ENMiUuOa_MnKjLTjcSo,6858
32
- industrial_model-0.1.31.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
33
- industrial_model-0.1.31.dist-info/RECORD,,
31
+ industrial_model-0.1.32.dist-info/METADATA,sha256=SgEMILIv7zqrEK1Wyb-l-74ixnL2s9KHvcUrOvvHeHo,6858
32
+ industrial_model-0.1.32.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
33
+ industrial_model-0.1.32.dist-info/RECORD,,