industrial-model 0.1.32__py3-none-any.whl → 0.1.34__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.
- industrial_model/cognite_adapters/__init__.py +3 -1
- industrial_model/cognite_adapters/aggregation_mapper.py +15 -11
- industrial_model/cognite_adapters/filter_mapper.py +1 -1
- industrial_model/cognite_adapters/optimizer.py +1 -1
- industrial_model/cognite_adapters/query_mapper.py +10 -5
- industrial_model/cognite_adapters/search_mapper.py +6 -6
- industrial_model/cognite_adapters/upsert_mapper.py +2 -2
- industrial_model/engines/engine.py +1 -1
- industrial_model/statements/__init__.py +45 -26
- {industrial_model-0.1.32.dist-info → industrial_model-0.1.34.dist-info}/METADATA +1 -1
- {industrial_model-0.1.32.dist-info → industrial_model-0.1.34.dist-info}/RECORD +12 -12
- {industrial_model-0.1.32.dist-info → industrial_model-0.1.34.dist-info}/WHEEL +0 -0
|
@@ -92,7 +92,9 @@ class CogniteAdapter:
|
|
|
92
92
|
next_cursor = query_result.cursors.get(view_external_id)
|
|
93
93
|
data.extend(page_result)
|
|
94
94
|
|
|
95
|
-
last_page =
|
|
95
|
+
last_page = (
|
|
96
|
+
len(page_result) < statement.get_values().limit or not next_cursor
|
|
97
|
+
)
|
|
96
98
|
next_cursor_ = None if last_page else next_cursor
|
|
97
99
|
cognite_query.cursors = {view_external_id: next_cursor_}
|
|
98
100
|
|
|
@@ -43,29 +43,33 @@ class AggregationMapper:
|
|
|
43
43
|
|
|
44
44
|
root_view = self._view_mapper.get_view(root_node)
|
|
45
45
|
|
|
46
|
+
statement_values = statement.get_values()
|
|
46
47
|
filters_ = (
|
|
47
|
-
filters.And(
|
|
48
|
-
|
|
48
|
+
filters.And(
|
|
49
|
+
*self._filter_mapper.map(statement_values.where_clauses, root_view)
|
|
50
|
+
)
|
|
51
|
+
if statement_values.where_clauses
|
|
49
52
|
else None
|
|
50
53
|
)
|
|
54
|
+
aggregation_property = statement_values.aggregation_property.property
|
|
51
55
|
metric_aggregation: MetricAggregation | None = None
|
|
52
56
|
if statement.aggregate == "avg":
|
|
53
|
-
metric_aggregation = Avg(
|
|
57
|
+
metric_aggregation = Avg(aggregation_property)
|
|
54
58
|
elif statement.aggregate == "min":
|
|
55
|
-
metric_aggregation = Min(
|
|
59
|
+
metric_aggregation = Min(aggregation_property)
|
|
56
60
|
elif statement.aggregate == "max":
|
|
57
|
-
metric_aggregation = Max(
|
|
61
|
+
metric_aggregation = Max(aggregation_property)
|
|
58
62
|
elif statement.aggregate == "sum":
|
|
59
|
-
metric_aggregation = Sum(
|
|
63
|
+
metric_aggregation = Sum(aggregation_property)
|
|
60
64
|
elif statement.aggregate == "count":
|
|
61
|
-
metric_aggregation = Count(
|
|
65
|
+
metric_aggregation = Count(aggregation_property)
|
|
62
66
|
|
|
63
67
|
if metric_aggregation is None:
|
|
64
|
-
raise ValueError(f"Unsupported aggregate function: {statement.
|
|
68
|
+
raise ValueError(f"Unsupported aggregate function: {statement.aggregate}")
|
|
65
69
|
|
|
66
70
|
group_by_columns = (
|
|
67
|
-
[prop.property for prop in
|
|
68
|
-
if
|
|
71
|
+
[prop.property for prop in statement_values.group_by_properties]
|
|
72
|
+
if statement_values.group_by_properties is not None
|
|
69
73
|
else statement.entity.get_group_by_fields()
|
|
70
74
|
)
|
|
71
75
|
return AggregationQuery(
|
|
@@ -73,5 +77,5 @@ class AggregationMapper:
|
|
|
73
77
|
metric_aggregation=metric_aggregation,
|
|
74
78
|
filters=filters_,
|
|
75
79
|
group_by_columns=group_by_columns,
|
|
76
|
-
limit=
|
|
80
|
+
limit=statement_values.limit,
|
|
77
81
|
)
|
|
@@ -12,10 +12,10 @@ from industrial_model.cognite_adapters.utils import get_property_ref
|
|
|
12
12
|
from industrial_model.models.entities import InstanceId
|
|
13
13
|
from industrial_model.statements import (
|
|
14
14
|
BoolExpression,
|
|
15
|
+
Column,
|
|
15
16
|
Expression,
|
|
16
17
|
LeafExpression,
|
|
17
18
|
)
|
|
18
|
-
from industrial_model.statements.expressions import Column
|
|
19
19
|
from industrial_model.utils import datetime_to_ms_iso_timestamp
|
|
20
20
|
|
|
21
21
|
from .view_mapper import ViewMapper
|
|
@@ -45,13 +45,16 @@ class QueryMapper:
|
|
|
45
45
|
|
|
46
46
|
filters_: list[filters.Filter] = [filters.HasData(views=[root_view_id])]
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
statement_values = statement.get_values()
|
|
49
|
+
filters_.extend(
|
|
50
|
+
self._filter_mapper.map(statement_values.where_clauses, root_view)
|
|
51
|
+
)
|
|
49
52
|
|
|
50
53
|
with_: dict[str, ResultSetExpression] = {
|
|
51
54
|
root_node: NodeResultSetExpression(
|
|
52
55
|
filter=filters.And(*filters_),
|
|
53
|
-
sort=self._sort_mapper.map(
|
|
54
|
-
limit=
|
|
56
|
+
sort=self._sort_mapper.map(statement_values.sort_clauses, root_view),
|
|
57
|
+
limit=statement_values.limit,
|
|
55
58
|
)
|
|
56
59
|
}
|
|
57
60
|
select_: dict[str, Select] = {}
|
|
@@ -59,7 +62,7 @@ class QueryMapper:
|
|
|
59
62
|
relations = get_schema_properties(statement.entity, NESTED_SEP, root_node)
|
|
60
63
|
|
|
61
64
|
edge_filters = self._filter_mapper.map_edges(
|
|
62
|
-
|
|
65
|
+
statement_values.where_edge_clauses, root_view, NESTED_SEP
|
|
63
66
|
)
|
|
64
67
|
|
|
65
68
|
properties = self._include_statements(
|
|
@@ -69,7 +72,9 @@ class QueryMapper:
|
|
|
69
72
|
select_[root_node] = self._get_select(root_view_id, properties)
|
|
70
73
|
|
|
71
74
|
return CogniteQuery(
|
|
72
|
-
with_=with_,
|
|
75
|
+
with_=with_,
|
|
76
|
+
select=select_,
|
|
77
|
+
cursors={root_node: statement_values.cursor},
|
|
73
78
|
)
|
|
74
79
|
|
|
75
80
|
def _get_select(self, view_id: ViewId, properties: list[str]) -> Select:
|
|
@@ -31,20 +31,20 @@ class SearchMapper:
|
|
|
31
31
|
|
|
32
32
|
def map(self, statement: SearchStatement[TViewInstance]) -> SearchQuery:
|
|
33
33
|
root_node = statement.entity.get_view_external_id()
|
|
34
|
-
|
|
34
|
+
statement_values = statement.get_values()
|
|
35
35
|
root_view = self._view_mapper.get_view(root_node)
|
|
36
36
|
|
|
37
|
-
filters_ = self._filter_mapper.map(
|
|
37
|
+
filters_ = self._filter_mapper.map(statement_values.where_clauses, root_view)
|
|
38
38
|
|
|
39
|
-
sort_clauses = self._sort_mapper.map(
|
|
39
|
+
sort_clauses = self._sort_mapper.map(statement_values.sort_clauses, root_view)
|
|
40
40
|
for item in sort_clauses:
|
|
41
41
|
item.nulls_first = None
|
|
42
42
|
|
|
43
43
|
return SearchQuery(
|
|
44
44
|
view=root_view,
|
|
45
45
|
filter=filters.And(*filters_) if filters_ else None,
|
|
46
|
-
query=
|
|
47
|
-
query_properties=
|
|
48
|
-
limit=
|
|
46
|
+
query=statement_values.query,
|
|
47
|
+
query_properties=statement_values.query_properties,
|
|
48
|
+
limit=statement_values.limit,
|
|
49
49
|
sort=sort_clauses,
|
|
50
50
|
)
|
|
@@ -102,10 +102,10 @@ class UpsertMapper:
|
|
|
102
102
|
return DirectRelationReference(
|
|
103
103
|
space=entry.space, external_id=entry.external_id
|
|
104
104
|
)
|
|
105
|
-
if isinstance(entry, datetime.date):
|
|
106
|
-
return entry.strftime("%Y-%m-%d")
|
|
107
105
|
if isinstance(entry, datetime.datetime):
|
|
108
106
|
return datetime_to_ms_iso_timestamp(entry)
|
|
107
|
+
if isinstance(entry, datetime.date):
|
|
108
|
+
return entry.strftime("%Y-%m-%d")
|
|
109
109
|
return entry
|
|
110
110
|
|
|
111
111
|
def _map_edges(
|
|
@@ -59,7 +59,7 @@ class Engine:
|
|
|
59
59
|
statement: Statement[TViewInstance],
|
|
60
60
|
validation_mode: ValidationMode = "raiseOnError",
|
|
61
61
|
) -> list[TViewInstance]:
|
|
62
|
-
if statement.
|
|
62
|
+
if statement.get_values().cursor:
|
|
63
63
|
raise ValueError("Cursor should be none when querying all pages")
|
|
64
64
|
|
|
65
65
|
data, _ = self._cognite_adapter.query(statement, True)
|
|
@@ -23,22 +23,36 @@ def _create_column(property: str | Column | Any) -> Column:
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
@dataclass
|
|
26
|
-
class
|
|
27
|
-
entity: type[T] = field(init=True)
|
|
26
|
+
class BaseStatementValues:
|
|
28
27
|
where_clauses: list[Expression] = field(init=False, default_factory=list)
|
|
28
|
+
where_edge_clauses: list[tuple[Column, list[Expression]]] = field(
|
|
29
|
+
init=False, default_factory=list
|
|
30
|
+
)
|
|
29
31
|
sort_clauses: list[tuple[Column, SORT_DIRECTION]] = field(
|
|
30
32
|
init=False, default_factory=list
|
|
31
33
|
)
|
|
32
|
-
|
|
34
|
+
limit: int = field(init=False, default=DEFAULT_LIMIT)
|
|
35
|
+
cursor: str | None = field(init=False, default=None)
|
|
36
|
+
|
|
37
|
+
query: str | None = field(init=False, default=None)
|
|
38
|
+
query_properties: list[str] | None = field(init=False, default=None)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class BaseStatement(Generic[T]):
|
|
43
|
+
entity: type[T] = field(init=True)
|
|
44
|
+
_values: BaseStatementValues = field(
|
|
45
|
+
init=False, default_factory=lambda: BaseStatementValues()
|
|
46
|
+
)
|
|
33
47
|
|
|
34
48
|
def where(self, *expressions: bool | Expression) -> Self:
|
|
35
49
|
for expression in expressions:
|
|
36
50
|
assert isinstance(expression, Expression)
|
|
37
|
-
self.where_clauses.append(expression)
|
|
51
|
+
self._values.where_clauses.append(expression)
|
|
38
52
|
return self
|
|
39
53
|
|
|
40
54
|
def limit(self, limit: int) -> Self:
|
|
41
|
-
self.
|
|
55
|
+
self._values.limit = limit
|
|
42
56
|
return self
|
|
43
57
|
|
|
44
58
|
def asc(self, property: str | Column | Any) -> Self:
|
|
@@ -48,7 +62,7 @@ class BaseStatement(Generic[T]):
|
|
|
48
62
|
return self.sort(property, "descending")
|
|
49
63
|
|
|
50
64
|
def sort(self, property: str | Column | Any, direction: SORT_DIRECTION) -> Self:
|
|
51
|
-
self.sort_clauses.append(
|
|
65
|
+
self._values.sort_clauses.append(
|
|
52
66
|
(
|
|
53
67
|
_create_column(property),
|
|
54
68
|
direction,
|
|
@@ -56,16 +70,14 @@ class BaseStatement(Generic[T]):
|
|
|
56
70
|
)
|
|
57
71
|
return self
|
|
58
72
|
|
|
73
|
+
def get_values(self) -> BaseStatementValues:
|
|
74
|
+
return self._values
|
|
75
|
+
|
|
59
76
|
|
|
60
77
|
@dataclass
|
|
61
78
|
class Statement(BaseStatement[T]):
|
|
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
|
-
)
|
|
66
|
-
|
|
67
79
|
def cursor(self, cursor: str | None) -> Self:
|
|
68
|
-
self.
|
|
80
|
+
self._values.cursor = cursor
|
|
69
81
|
return self
|
|
70
82
|
|
|
71
83
|
def where_edge(
|
|
@@ -79,7 +91,7 @@ class Statement(BaseStatement[T]):
|
|
|
79
91
|
assert isinstance(expression, Expression)
|
|
80
92
|
expressions_.append(expression)
|
|
81
93
|
|
|
82
|
-
self.where_edge_clauses.append(
|
|
94
|
+
self._values.where_edge_clauses.append(
|
|
83
95
|
(
|
|
84
96
|
_create_column(property),
|
|
85
97
|
expressions_,
|
|
@@ -90,16 +102,13 @@ class Statement(BaseStatement[T]):
|
|
|
90
102
|
|
|
91
103
|
@dataclass
|
|
92
104
|
class SearchStatement(BaseStatement[T]):
|
|
93
|
-
query: str | None = field(init=False, default=None)
|
|
94
|
-
query_properties: list[str] | None = field(init=False, default=None)
|
|
95
|
-
|
|
96
105
|
def query_by(
|
|
97
106
|
self,
|
|
98
107
|
query: str,
|
|
99
108
|
query_properties: list[Column] | list[str] | list[Any] | None = None,
|
|
100
109
|
) -> Self:
|
|
101
|
-
self.query = query
|
|
102
|
-
self.query_properties = (
|
|
110
|
+
self._values.query = query
|
|
111
|
+
self._values.query_properties = (
|
|
103
112
|
[
|
|
104
113
|
prop
|
|
105
114
|
if isinstance(prop, str)
|
|
@@ -114,34 +123,44 @@ class SearchStatement(BaseStatement[T]):
|
|
|
114
123
|
return self
|
|
115
124
|
|
|
116
125
|
|
|
126
|
+
@dataclass
|
|
127
|
+
class AggregationStatementValues:
|
|
128
|
+
group_by_properties: list[Column] | None = field(init=False, default=None)
|
|
129
|
+
aggregation_property: Column = field(init=False, default=Column("externalId"))
|
|
130
|
+
where_clauses: list[Expression] = field(init=False, default_factory=list)
|
|
131
|
+
limit: int = field(init=False, default=-1)
|
|
132
|
+
|
|
133
|
+
|
|
117
134
|
@dataclass
|
|
118
135
|
class AggregationStatement(Generic[T]):
|
|
119
136
|
entity: type[T] = field(init=True)
|
|
120
137
|
aggregate: AggregateTypes = field(init=True)
|
|
121
138
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
limit_: int = field(init=False, default=-1)
|
|
139
|
+
_values: AggregationStatementValues = field(
|
|
140
|
+
init=False, default_factory=lambda: AggregationStatementValues()
|
|
141
|
+
)
|
|
126
142
|
|
|
127
143
|
def group_by(self, *property: str | Column | Any) -> Self:
|
|
128
|
-
self.group_by_properties = [_create_column(prop) for prop in property]
|
|
144
|
+
self._values.group_by_properties = [_create_column(prop) for prop in property]
|
|
129
145
|
return self
|
|
130
146
|
|
|
131
147
|
def aggregate_by(self, property: str | Column | Any) -> Self:
|
|
132
|
-
self.aggregation_property = _create_column(property)
|
|
148
|
+
self._values.aggregation_property = _create_column(property)
|
|
133
149
|
return self
|
|
134
150
|
|
|
135
151
|
def where(self, *expressions: bool | Expression) -> Self:
|
|
136
152
|
for expression in expressions:
|
|
137
153
|
assert isinstance(expression, Expression)
|
|
138
|
-
self.where_clauses.append(expression)
|
|
154
|
+
self._values.where_clauses.append(expression)
|
|
139
155
|
return self
|
|
140
156
|
|
|
141
157
|
def limit(self, limit: int) -> Self:
|
|
142
|
-
self.
|
|
158
|
+
self._values.limit = limit
|
|
143
159
|
return self
|
|
144
160
|
|
|
161
|
+
def get_values(self) -> AggregationStatementValues:
|
|
162
|
+
return self._values
|
|
163
|
+
|
|
145
164
|
|
|
146
165
|
def select(entity: type[T]) -> Statement[T]:
|
|
147
166
|
return Statement(entity)
|
|
@@ -3,21 +3,21 @@ industrial_model/config.py,sha256=LseCZ8JvewFejjElPUQWdmIQQUU2wnd43McDid_Rixs,47
|
|
|
3
3
|
industrial_model/constants.py,sha256=wtFdxkR9gojqekwXeyVCof6VUkJYuqjjgAgVVKrcxaw,450
|
|
4
4
|
industrial_model/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
industrial_model/utils.py,sha256=oh4AxwxXaWgIC2uolkCbvkgo0ququHB6yAPVIXy45Ts,663
|
|
6
|
-
industrial_model/cognite_adapters/__init__.py,sha256
|
|
7
|
-
industrial_model/cognite_adapters/aggregation_mapper.py,sha256=
|
|
8
|
-
industrial_model/cognite_adapters/filter_mapper.py,sha256=
|
|
6
|
+
industrial_model/cognite_adapters/__init__.py,sha256=-cUnErbtDV4XOT_p5xAp28IiH9DPFhE8lsoPa_foq1o,6290
|
|
7
|
+
industrial_model/cognite_adapters/aggregation_mapper.py,sha256=CYbOR7Eh447PEwCtPKFCHYh3-K6akwLTJdQ-oeSYvKo,2599
|
|
8
|
+
industrial_model/cognite_adapters/filter_mapper.py,sha256=eSrEYdEKZHQuJ98gblBYy1qCe5VYpq3fjLSUg8614fk,5261
|
|
9
9
|
industrial_model/cognite_adapters/models.py,sha256=2j2IS01uPkQEp9WdVk8seYzEqGcDdWFnpzXhusHB2zk,945
|
|
10
|
-
industrial_model/cognite_adapters/optimizer.py,sha256=
|
|
11
|
-
industrial_model/cognite_adapters/query_mapper.py,sha256=
|
|
10
|
+
industrial_model/cognite_adapters/optimizer.py,sha256=kdRlliYacNkONxSHC84U3EjONkIfP7h-OOSL_T5Okg8,2428
|
|
11
|
+
industrial_model/cognite_adapters/query_mapper.py,sha256=tpRdrEW6i0NKy5h6bYrIIP96nanPSokK-s5-1d0PES8,6597
|
|
12
12
|
industrial_model/cognite_adapters/query_result_mapper.py,sha256=KaBqYr5l1t8sQMxEoX_F3J2prypKIPaDJxSzGF_fMB8,10203
|
|
13
|
-
industrial_model/cognite_adapters/search_mapper.py,sha256=
|
|
13
|
+
industrial_model/cognite_adapters/search_mapper.py,sha256=zRe5FgucTWHX2VVbh3iLmzM7FmUAFhJG5t42gXnnJrE,1587
|
|
14
14
|
industrial_model/cognite_adapters/sort_mapper.py,sha256=RJUAYlZGXoYzK0PwX63cibRF_L-MUq9g2ZsC2EeNIF4,696
|
|
15
|
-
industrial_model/cognite_adapters/upsert_mapper.py,sha256=
|
|
15
|
+
industrial_model/cognite_adapters/upsert_mapper.py,sha256=jzelnmECFcuVkQY7dgZG-xL19yD9kxtYvx827InIMO8,4951
|
|
16
16
|
industrial_model/cognite_adapters/utils.py,sha256=-9NUG84r49cKvmmzoUinxNF1zhHIlmoWFypUCD_WTeM,4800
|
|
17
17
|
industrial_model/cognite_adapters/view_mapper.py,sha256=fihoxyLKvq8xa1oArdCCkukqVpOexFcBDnEyMACpHF8,1430
|
|
18
18
|
industrial_model/engines/__init__.py,sha256=7aGHrUm2MxIq39vR8h0xu3i1zNOuT9H9U-q4lV3nErQ,102
|
|
19
19
|
industrial_model/engines/async_engine.py,sha256=-sQv2vn93bBmTZOxY_C1r40YP7IMl1ND2gCN2GE9BqY,2188
|
|
20
|
-
industrial_model/engines/engine.py,sha256=
|
|
20
|
+
industrial_model/engines/engine.py,sha256=Pwg8A3PFVdRExiLGyhcs8hhiGyKgKi6piOmiLgvCL50,3810
|
|
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
23
|
industrial_model/models/entities.py,sha256=XugtGFCJrHnxR4UX7FWFumB2tNZGB7mNjM4skznnmdQ,4704
|
|
@@ -26,8 +26,8 @@ industrial_model/queries/__init__.py,sha256=lA83zOxMRgBgkseWJgK9kCr1vD8D8iSWs9NG
|
|
|
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=
|
|
29
|
+
industrial_model/statements/__init__.py,sha256=3Et9PM7AMbIS7Fh9051Q0u3qUpX6588d1yuNrvdd4wI,5429
|
|
30
30
|
industrial_model/statements/expressions.py,sha256=4ZZOcZroI5-4xRw4PXIRlufi0ARndE5zSbbxLDpR2Ec,4816
|
|
31
|
-
industrial_model-0.1.
|
|
32
|
-
industrial_model-0.1.
|
|
33
|
-
industrial_model-0.1.
|
|
31
|
+
industrial_model-0.1.34.dist-info/METADATA,sha256=9rtluwI-0-GwC1dqVlIUaCSPL8jdx6DNEVSIXhJ0qVU,6858
|
|
32
|
+
industrial_model-0.1.34.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
33
|
+
industrial_model-0.1.34.dist-info/RECORD,,
|
|
File without changes
|