industrial-model 0.1.22__py3-none-any.whl → 0.1.24__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.
@@ -62,10 +62,16 @@ class AggregationMapper:
62
62
 
63
63
  if metric_aggregation is None:
64
64
  raise ValueError(f"Unsupported aggregate function: {statement.aggregate_}")
65
+
66
+ group_by_columns = (
67
+ [prop.property for prop in statement.group_by_properties]
68
+ if statement.group_by_properties is not None
69
+ else statement.entity.get_group_by_fields()
70
+ )
65
71
  return AggregationQuery(
66
72
  view=root_view,
67
73
  metric_aggregation=metric_aggregation,
68
74
  filters=filters_,
69
- group_by_columns=statement.entity.get_group_by_fields(),
75
+ group_by_columns=group_by_columns,
70
76
  limit=statement.limit_,
71
77
  )
@@ -1,9 +1,11 @@
1
1
  from datetime import date, datetime
2
+ from typing import Any
2
3
 
3
4
  import cognite.client.data_classes.filters as cdf_filters
4
5
  from cognite.client.data_classes.data_modeling import MappedProperty, View
5
6
 
6
7
  from industrial_model.cognite_adapters.utils import get_property_ref
8
+ from industrial_model.models.entities import InstanceId
7
9
  from industrial_model.statements import (
8
10
  BoolExpression,
9
11
  Expression,
@@ -54,11 +56,8 @@ class FilterMapper:
54
56
  property_ref = get_property_ref(expression.property, root_view)
55
57
 
56
58
  value_ = expression.value
57
- if isinstance(value_, datetime):
58
- value_ = datetime_to_ms_iso_timestamp(value_)
59
59
 
60
- if isinstance(value_, date):
61
- value_ = value_.strftime("%Y-%m-%d")
60
+ value_ = self._handle_type_value_convertion(value_)
62
61
 
63
62
  if expression.operator == "==":
64
63
  return cdf_filters.Equals(property_ref, value_)
@@ -96,3 +95,14 @@ class FilterMapper:
96
95
  assert isinstance(view_definiton, MappedProperty)
97
96
  assert view_definiton.source
98
97
  return self._view_mapper.get_view(view_definiton.source.external_id)
98
+
99
+ def _handle_type_value_convertion(self, value_: Any) -> Any:
100
+ if isinstance(value_, datetime):
101
+ return datetime_to_ms_iso_timestamp(value_)
102
+ elif isinstance(value_, date):
103
+ return value_.strftime("%Y-%m-%d")
104
+ elif isinstance(value_, InstanceId):
105
+ return value_.model_dump(mode="json", by_alias=True)
106
+ elif isinstance(value_, list):
107
+ return [self._handle_type_value_convertion(v) for v in value_]
108
+ return value_
@@ -1,9 +1,11 @@
1
- from .models import BasePaginatedQuery, BaseQuery
1
+ from .models import BaseAggregationQuery, BasePaginatedQuery, BaseQuery, BaseSearchQuery
2
2
  from .params import NestedQueryParam, QueryParam, SortParam
3
3
 
4
4
  __all__ = [
5
5
  "BaseQuery",
6
6
  "BasePaginatedQuery",
7
+ "BaseSearchQuery",
8
+ "BaseAggregationQuery",
7
9
  "SortParam",
8
10
  "QueryParam",
9
11
  "NestedQueryParam",
@@ -1,5 +1,13 @@
1
- from industrial_model.models import RootModel, TViewInstance
2
- from industrial_model.statements import Statement
1
+ from typing import Any
2
+
3
+ from industrial_model.models import RootModel, TAggregatedViewInstance, TViewInstance
4
+ from industrial_model.statements import (
5
+ AggregateTypes,
6
+ AggregationStatement,
7
+ SearchStatement,
8
+ Statement,
9
+ aggregate,
10
+ )
3
11
 
4
12
  from .params import NestedQueryParam, QueryParam, SortParam
5
13
 
@@ -31,3 +39,60 @@ class BasePaginatedQuery(BaseQuery):
31
39
  statement.cursor(self.cursor)
32
40
 
33
41
  return statement
42
+
43
+
44
+ class BaseSearchQuery(RootModel):
45
+ query: str | None = None
46
+ query_properties: list[str] | list[Any] | None = None
47
+ limit: int = 1000
48
+
49
+ def to_statement(
50
+ self, entity: type[TViewInstance]
51
+ ) -> SearchStatement[TViewInstance]:
52
+ statement = SearchStatement(entity)
53
+
54
+ for key, item in self.__class__.model_fields.items():
55
+ values = getattr(self, key)
56
+ if not values:
57
+ continue
58
+ for metadata_item in item.metadata:
59
+ if isinstance(metadata_item, SortParam):
60
+ statement.sort(values, metadata_item.direction)
61
+ elif isinstance(metadata_item, QueryParam | NestedQueryParam):
62
+ statement.where(metadata_item.to_expression(values))
63
+ if self.query:
64
+ statement.query_by(self.query, self.query_properties)
65
+ statement.limit(self.limit)
66
+
67
+ return statement
68
+
69
+
70
+ class BaseAggregationQuery(RootModel):
71
+ aggregate: AggregateTypes | None = None
72
+ group_by_properties: list[str] | list[Any] | None = None
73
+ aggregation_property: str | None = None
74
+ limit: int | None = None
75
+
76
+ def to_statement(
77
+ self, entity: type[TAggregatedViewInstance]
78
+ ) -> AggregationStatement[TAggregatedViewInstance]:
79
+ statement = aggregate(entity, self.aggregate)
80
+
81
+ for key, item in self.__class__.model_fields.items():
82
+ values = getattr(self, key)
83
+ if not values:
84
+ continue
85
+ for metadata_item in item.metadata:
86
+ if isinstance(metadata_item, QueryParam | NestedQueryParam):
87
+ statement.where(metadata_item.to_expression(values))
88
+
89
+ if self.group_by_properties:
90
+ statement.group_by(*self.group_by_properties)
91
+
92
+ if self.aggregation_property:
93
+ statement.aggregate_by(self.aggregation_property)
94
+
95
+ if self.limit:
96
+ statement.limit(self.limit)
97
+
98
+ return statement
@@ -74,7 +74,7 @@ class SearchStatement(BaseStatement[T]):
74
74
  def query_by(
75
75
  self,
76
76
  query: str,
77
- query_properties: list[Column | str | Any] | None = None,
77
+ query_properties: list[Column] | list[str] | list[Any] | None = None,
78
78
  ) -> Self:
79
79
  self.query = query
80
80
  self.query_properties = (
@@ -97,10 +97,15 @@ class AggregationStatement(Generic[T]):
97
97
  entity: type[T] = field(init=True)
98
98
  aggregate: AggregateTypes = field(init=True)
99
99
 
100
+ group_by_properties: list[Column] | None = field(init=False, default=None)
100
101
  aggregation_property: Column = field(init=False, default=Column("externalId"))
101
102
  where_clauses: list[Expression] = field(init=False, default_factory=list)
102
103
  limit_: int = field(init=False, default=-1)
103
104
 
105
+ def group_by(self, *property: str | Column | Any) -> Self:
106
+ self.group_by_properties = [_create_column(prop) for prop in property]
107
+ return self
108
+
104
109
  def aggregate_by(self, property: str | Column | Any) -> Self:
105
110
  self.aggregation_property = _create_column(property)
106
111
  return self
@@ -122,9 +127,9 @@ def select(entity: type[T]) -> Statement[T]:
122
127
 
123
128
  def aggregate(
124
129
  entity: type[T],
125
- aggregate: AggregateTypes = "count",
130
+ aggregate: AggregateTypes | None = "count",
126
131
  ) -> AggregationStatement[T]:
127
- return AggregationStatement(entity=entity, aggregate=aggregate)
132
+ return AggregationStatement(entity=entity, aggregate=aggregate or "count")
128
133
 
129
134
 
130
135
  def search(entity: type[T]) -> SearchStatement[T]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: industrial-model
3
- Version: 0.1.22
3
+ Version: 0.1.24
4
4
  Summary: Industrial Model ORM
5
5
  Author-email: Lucas Alves <lucasrosaalves@gmail.com>
6
6
  Classifier: Programming Language :: Python
@@ -4,8 +4,8 @@ industrial_model/constants.py,sha256=wtFdxkR9gojqekwXeyVCof6VUkJYuqjjgAgVVKrcxaw
4
4
  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
- industrial_model/cognite_adapters/aggregation_mapper.py,sha256=w9EksY-_pNrc15DXHVRydfMdmPbvu4dzCRhzRB3F7QM,2302
8
- industrial_model/cognite_adapters/filter_mapper.py,sha256=xXTzxCYKU1-6TxG5W_bb8zNyWi2bfIM9RiujyOHUujg,3900
7
+ industrial_model/cognite_adapters/aggregation_mapper.py,sha256=qglWUnyhgSPG005HzIRyjYkt9V2WKsab5y4ruwuKLcA,2503
8
+ industrial_model/cognite_adapters/filter_mapper.py,sha256=R_OX8JOM33vzBVFvfo0iDmSJl5rhGjsTBLyKDoesHO0,4349
9
9
  industrial_model/cognite_adapters/models.py,sha256=2j2IS01uPkQEp9WdVk8seYzEqGcDdWFnpzXhusHB2zk,945
10
10
  industrial_model/cognite_adapters/optimizer.py,sha256=EQfCe-4mSeXhYa2kcqJerPXYsCRgMJPA1AIf1o1KNH0,2415
11
11
  industrial_model/cognite_adapters/query_mapper.py,sha256=QdFVkfmL4tWcCy_oypOluT0Fo68obPk2RjBPvVA9mUs,5950
@@ -22,11 +22,11 @@ industrial_model/models/__init__.py,sha256=AzJ0CyPK5PvUCX45FFtybl13tkukUvk2UAF_9
22
22
  industrial_model/models/base.py,sha256=iGhDjXqA5ULEQIFHtkMi7WYJl0nQq1wi8_zqOr-Ep78,1649
23
23
  industrial_model/models/entities.py,sha256=tHOFjS-9XsaXVrZ-x0tZR1DWL2Cc8MHe82qsIazqmnM,2811
24
24
  industrial_model/models/schemas.py,sha256=EoLK9GYdS-0DQ98myTP3wOU9YpWIJOfDSLOYZUy3xEY,4559
25
- industrial_model/queries/__init__.py,sha256=7aheTE5qs03rxWm9fmGWptbz_p9OIXXYD8if56cqs18,227
26
- industrial_model/queries/models.py,sha256=zb2riqpB5S6BoKRqnau8MHjsrU980MOCDTbyB3hjXYY,1157
25
+ industrial_model/queries/__init__.py,sha256=0cF-KTTGHLhdFKe3T_5cEVHsTN95iAV7R6FUutvuoaU,317
26
+ industrial_model/queries/models.py,sha256=wn4I8bTUGCT5keF6mUA7bEYNgSsOxeN-zibY5CYhzj8,3267
27
27
  industrial_model/queries/params.py,sha256=ehgCoR5n6E-tkEuoymZ2lkLcSzMaBAx_HnyJ7sWpqz0,964
28
- industrial_model/statements/__init__.py,sha256=_79ZJrJNJ4XjiDJDJld-kh4DOWA3zWqY6npe6HHP8hM,3949
28
+ industrial_model/statements/__init__.py,sha256=rjLRo2KoazHQaOpmPkxbI3_Nm8NCkJxjpuqow6IZVSc,4221
29
29
  industrial_model/statements/expressions.py,sha256=4ZZOcZroI5-4xRw4PXIRlufi0ARndE5zSbbxLDpR2Ec,4816
30
- industrial_model-0.1.22.dist-info/METADATA,sha256=UPKMtUmBdYCfPW6wi67vfiHpajTHo2WJD_oPL0tqACA,6858
31
- industrial_model-0.1.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- industrial_model-0.1.22.dist-info/RECORD,,
30
+ industrial_model-0.1.24.dist-info/METADATA,sha256=F8lZBHy_GghR4NABWGDlVrQdITuncMGQ0FF89ZCCHQg,6858
31
+ industrial_model-0.1.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ industrial_model-0.1.24.dist-info/RECORD,,