industrial-model 0.1.12__tar.gz → 0.1.13__tar.gz

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.
Files changed (44) hide show
  1. {industrial_model-0.1.12 → industrial_model-0.1.13}/PKG-INFO +27 -13
  2. {industrial_model-0.1.12 → industrial_model-0.1.13}/README.md +26 -12
  3. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/__init__.py +4 -2
  4. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/__init__.py +12 -13
  5. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/aggregation_mapper.py +22 -11
  6. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/filter_mapper.py +4 -1
  7. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/engines/async_engine.py +3 -3
  8. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/engines/engine.py +6 -4
  9. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/models/__init__.py +4 -2
  10. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/models/base.py +11 -0
  11. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/models/entities.py +23 -17
  12. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/statements/__init__.py +11 -14
  13. {industrial_model-0.1.12 → industrial_model-0.1.13}/pyproject.toml +1 -1
  14. {industrial_model-0.1.12 → industrial_model-0.1.13}/tests/models.py +9 -0
  15. {industrial_model-0.1.12 → industrial_model-0.1.13}/tests/tests_adapter.py +15 -4
  16. industrial_model-0.1.13/tests/tests_aggregate.py +19 -0
  17. {industrial_model-0.1.12 → industrial_model-0.1.13}/uv.lock +1 -1
  18. {industrial_model-0.1.12 → industrial_model-0.1.13}/.gitignore +0 -0
  19. {industrial_model-0.1.12 → industrial_model-0.1.13}/.python-version +0 -0
  20. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/models.py +0 -0
  21. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/optimizer.py +0 -0
  22. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/query_mapper.py +0 -0
  23. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/query_result_mapper.py +0 -0
  24. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/sort_mapper.py +0 -0
  25. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/upsert_mapper.py +0 -0
  26. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/utils.py +0 -0
  27. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/cognite_adapters/view_mapper.py +0 -0
  28. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/config.py +0 -0
  29. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/constants.py +0 -0
  30. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/engines/__init__.py +0 -0
  31. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/models/schemas.py +0 -0
  32. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/py.typed +0 -0
  33. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/queries/__init__.py +0 -0
  34. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/queries/models.py +0 -0
  35. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/queries/params.py +0 -0
  36. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/statements/expressions.py +0 -0
  37. {industrial_model-0.1.12 → industrial_model-0.1.13}/industrial_model/utils.py +0 -0
  38. {industrial_model-0.1.12 → industrial_model-0.1.13}/scripts/build.sh +0 -0
  39. {industrial_model-0.1.12 → industrial_model-0.1.13}/scripts/format.sh +0 -0
  40. {industrial_model-0.1.12 → industrial_model-0.1.13}/scripts/lint.sh +0 -0
  41. {industrial_model-0.1.12 → industrial_model-0.1.13}/tests/__init__.py +0 -0
  42. {industrial_model-0.1.12 → industrial_model-0.1.13}/tests/cognite-sdk-config.yaml +0 -0
  43. {industrial_model-0.1.12 → industrial_model-0.1.13}/tests/hubs.py +0 -0
  44. {industrial_model-0.1.12 → industrial_model-0.1.13}/tests/test_upsert_mapper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: industrial-model
3
- Version: 0.1.12
3
+ Version: 0.1.13
4
4
  Summary: Industrial Model ORM
5
5
  Author-email: Lucas Alves <lucasrosaalves@gmail.com>
6
6
  Classifier: Programming Language :: Python
@@ -50,14 +50,19 @@ from cognite.client import CogniteClient
50
50
  from pydantic import Field
51
51
 
52
52
  from industrial_model import (
53
+ aggregate,
54
+ AggregatedViewInstance,
53
55
  AsyncEngine,
54
56
  DataModelId,
55
57
  Engine,
58
+ InstanceId,
56
59
  ViewInstance,
57
- select,
58
- col,
60
+ ViewInstanceConfig,
61
+ WritableViewInstance,
59
62
  and_,
63
+ col,
60
64
  or_,
65
+ select,
61
66
  )
62
67
 
63
68
  # Define entities (view instances)
@@ -184,12 +189,10 @@ all_results = engine.query_all_pages(statement)
184
189
 
185
190
  # 7. Data Ingestion
186
191
 
187
- from industrial_model import (
188
- WritableViewInstance # necessary for data ingestion
189
- )
190
-
191
-
192
192
  class WritablePerson(WritableViewInstance):
193
+ view_config = ViewInstanceConfig(
194
+ view_external_id="Person" # Maps this class to the 'Person' view
195
+ )
193
196
  name: str
194
197
  lives_in: InstanceId
195
198
  cars: list[InstanceId]
@@ -203,10 +206,7 @@ class WritablePerson(WritableViewInstance):
203
206
  space=self.space,
204
207
  )
205
208
 
206
- statement = select(WritablePerson).where(
207
- (WritablePerson.external_id == "Lucas")
208
- )
209
-
209
+ statement = select(WritablePerson).where(WritablePerson.external_id == "Lucas")
210
210
  person = engine.query_all_pages(statement)[0]
211
211
 
212
212
  person.lives_in = InstanceId(external_id="br", space="data-space")
@@ -214,7 +214,21 @@ person.cars.clear() # Gonna remove all car edges from the person
214
214
 
215
215
  engine.upsert([person])
216
216
 
217
- ```
218
217
 
219
218
 
219
+ # 8. Aggregate
220
+
221
+ class AggregateByNamePerson(AggregatedViewInstance):
222
+ view_config = ViewInstanceConfig(
223
+ view_external_id="Person" # Maps this class to the 'Person' view
224
+ )
225
+
226
+ name: str # group by name
227
+
228
+
229
+ aggregate_result = engine.aggregate(aggregate(AggregateByNamePerson, "count"))
230
+
231
+
232
+ ```
233
+
220
234
  ---
@@ -30,14 +30,19 @@ from cognite.client import CogniteClient
30
30
  from pydantic import Field
31
31
 
32
32
  from industrial_model import (
33
+ aggregate,
34
+ AggregatedViewInstance,
33
35
  AsyncEngine,
34
36
  DataModelId,
35
37
  Engine,
38
+ InstanceId,
36
39
  ViewInstance,
37
- select,
38
- col,
40
+ ViewInstanceConfig,
41
+ WritableViewInstance,
39
42
  and_,
43
+ col,
40
44
  or_,
45
+ select,
41
46
  )
42
47
 
43
48
  # Define entities (view instances)
@@ -164,12 +169,10 @@ all_results = engine.query_all_pages(statement)
164
169
 
165
170
  # 7. Data Ingestion
166
171
 
167
- from industrial_model import (
168
- WritableViewInstance # necessary for data ingestion
169
- )
170
-
171
-
172
172
  class WritablePerson(WritableViewInstance):
173
+ view_config = ViewInstanceConfig(
174
+ view_external_id="Person" # Maps this class to the 'Person' view
175
+ )
173
176
  name: str
174
177
  lives_in: InstanceId
175
178
  cars: list[InstanceId]
@@ -183,10 +186,7 @@ class WritablePerson(WritableViewInstance):
183
186
  space=self.space,
184
187
  )
185
188
 
186
- statement = select(WritablePerson).where(
187
- (WritablePerson.external_id == "Lucas")
188
- )
189
-
189
+ statement = select(WritablePerson).where(WritablePerson.external_id == "Lucas")
190
190
  person = engine.query_all_pages(statement)[0]
191
191
 
192
192
  person.lives_in = InstanceId(external_id="br", space="data-space")
@@ -194,7 +194,21 @@ person.cars.clear() # Gonna remove all car edges from the person
194
194
 
195
195
  engine.upsert([person])
196
196
 
197
- ```
198
197
 
199
198
 
199
+ # 8. Aggregate
200
+
201
+ class AggregateByNamePerson(AggregatedViewInstance):
202
+ view_config = ViewInstanceConfig(
203
+ view_external_id="Person" # Maps this class to the 'Person' view
204
+ )
205
+
206
+ name: str # group by name
207
+
208
+
209
+ aggregate_result = engine.aggregate(aggregate(AggregateByNamePerson, "count"))
210
+
211
+
212
+ ```
213
+
200
214
  ---
@@ -1,9 +1,10 @@
1
1
  from .config import DataModelId
2
2
  from .engines import AsyncEngine, Engine
3
3
  from .models import (
4
- AggregationResult,
4
+ AggregatedViewInstance,
5
5
  InstanceId,
6
6
  PaginatedResult,
7
+ TAggregatedViewInstance,
7
8
  TViewInstance,
8
9
  TWritableViewInstance,
9
10
  ValidationMode,
@@ -15,7 +16,7 @@ from .statements import aggregate, and_, col, not_, or_, select
15
16
 
16
17
  __all__ = [
17
18
  "aggregate",
18
- "AggregationResult",
19
+ "AggregatedViewInstance",
19
20
  "and_",
20
21
  "or_",
21
22
  "col",
@@ -25,6 +26,7 @@ __all__ = [
25
26
  "InstanceId",
26
27
  "TViewInstance",
27
28
  "DataModelId",
29
+ "TAggregatedViewInstance",
28
30
  "TWritableViewInstance",
29
31
  "ValidationMode",
30
32
  "Engine",
@@ -12,7 +12,7 @@ from cognite.client.data_classes.data_modeling.query import (
12
12
 
13
13
  from industrial_model.config import DataModelId
14
14
  from industrial_model.models import (
15
- AggregationResult,
15
+ TAggregatedViewInstance,
16
16
  TViewInstance,
17
17
  TWritableViewInstance,
18
18
  )
@@ -83,8 +83,8 @@ class CogniteAdapter:
83
83
  return data, next_cursor_
84
84
 
85
85
  def aggregate(
86
- self, statement: AggregationStatement[TViewInstance]
87
- ) -> list[AggregationResult]:
86
+ self, statement: AggregationStatement[TAggregatedViewInstance]
87
+ ) -> list[dict[str, Any]]:
88
88
  query = self._aggregation_mapper.map(statement)
89
89
 
90
90
  result = self._cognite_client.data_modeling.instances.aggregate(
@@ -94,16 +94,15 @@ class CogniteAdapter:
94
94
  group_by=query.group_by_columns,
95
95
  limit=query.limit,
96
96
  )
97
-
98
- return [
99
- AggregationResult(
100
- group=item.group,
101
- value=item.aggregates[0].value,
102
- aggregate=statement.aggregate_,
103
- )
104
- for item in result
105
- if item.aggregates and item.aggregates[0].value is not None
106
- ]
97
+ data: list[dict[str, Any]] = []
98
+ for item in result:
99
+ if not item.aggregates or item.aggregates[0].value is None:
100
+ continue
101
+
102
+ entry = item.group if item.group else {}
103
+ entry["value"] = item.aggregates[0].value
104
+ data.append(entry)
105
+ return data
107
106
 
108
107
  def upsert(
109
108
  self, entries: list[TWritableViewInstance], replace: bool = False
@@ -1,12 +1,19 @@
1
1
  from dataclasses import dataclass
2
2
 
3
3
  import cognite.client.data_classes.filters as filters
4
- from cognite.client.data_classes.aggregations import Count, MetricAggregation
4
+ from cognite.client.data_classes.aggregations import (
5
+ Avg,
6
+ Count,
7
+ Max,
8
+ MetricAggregation,
9
+ Min,
10
+ Sum,
11
+ )
5
12
  from cognite.client.data_classes.data_modeling import (
6
13
  View,
7
14
  )
8
15
 
9
- from industrial_model.models import TViewInstance
16
+ from industrial_model.models import TAggregatedViewInstance
10
17
  from industrial_model.statements import AggregationStatement
11
18
 
12
19
  from .filter_mapper import (
@@ -30,7 +37,7 @@ class AggregationMapper:
30
37
  self._filter_mapper = FilterMapper(view_mapper)
31
38
 
32
39
  def map(
33
- self, statement: AggregationStatement[TViewInstance]
40
+ self, statement: AggregationStatement[TAggregatedViewInstance]
34
41
  ) -> AggregationQuery:
35
42
  root_node = statement.entity.get_view_external_id()
36
43
 
@@ -43,12 +50,18 @@ class AggregationMapper:
43
50
  if statement.where_clauses
44
51
  else None
45
52
  )
53
+ metric_aggregation: MetricAggregation | None = None
54
+ if statement.aggregate == "avg":
55
+ metric_aggregation = Avg(statement.aggregation_property.property)
56
+ elif statement.aggregate == "min":
57
+ metric_aggregation = Min(statement.aggregation_property.property)
58
+ elif statement.aggregate == "max":
59
+ metric_aggregation = Max(statement.aggregation_property.property)
60
+ elif statement.aggregate == "sum":
61
+ metric_aggregation = Sum(statement.aggregation_property.property)
62
+ elif statement.aggregate == "count":
63
+ metric_aggregation = Count(statement.aggregation_property.property)
46
64
 
47
- metric_aggregation = (
48
- Count(statement.aggregation_property.property)
49
- if statement.aggregate_ == "count"
50
- else None
51
- )
52
65
  if metric_aggregation is None:
53
66
  raise ValueError(
54
67
  f"Unsupported aggregate function: {statement.aggregate_}"
@@ -57,8 +70,6 @@ class AggregationMapper:
57
70
  view=root_view,
58
71
  metric_aggregation=metric_aggregation,
59
72
  filters=filters_,
60
- group_by_columns=[
61
- column.property for column in statement.group_by_columns
62
- ],
73
+ group_by_columns=statement.entity.get_group_by_fields(),
63
74
  limit=statement.limit_,
64
75
  )
@@ -1,4 +1,4 @@
1
- from datetime import datetime
1
+ from datetime import date, datetime
2
2
 
3
3
  import cognite.client.data_classes.filters as cdf_filters
4
4
  from cognite.client.data_classes.data_modeling import MappedProperty, View
@@ -57,6 +57,9 @@ class FilterMapper:
57
57
  if isinstance(value_, datetime):
58
58
  value_ = datetime_to_ms_iso_timestamp(value_)
59
59
 
60
+ if isinstance(value_, date):
61
+ value_ = value_.strftime("%Y-%m-%d")
62
+
60
63
  if expression.operator == "==":
61
64
  return cdf_filters.Equals(property_ref, value_)
62
65
  elif expression.operator == "in":
@@ -2,8 +2,8 @@ from cognite.client import CogniteClient
2
2
 
3
3
  from industrial_model.config import DataModelId
4
4
  from industrial_model.models import (
5
- AggregationResult,
6
5
  PaginatedResult,
6
+ TAggregatedViewInstance,
7
7
  TViewInstance,
8
8
  TWritableViewInstance,
9
9
  ValidationMode,
@@ -39,8 +39,8 @@ class AsyncEngine:
39
39
  )
40
40
 
41
41
  async def aggregate_async(
42
- self, statement: AggregationStatement[TViewInstance]
43
- ) -> list[AggregationResult]:
42
+ self, statement: AggregationStatement[TAggregatedViewInstance]
43
+ ) -> list[TAggregatedViewInstance]:
44
44
  return await run_async(self._engine.aggregate, statement)
45
45
 
46
46
  async def upsert_async(
@@ -5,9 +5,9 @@ from cognite.client import CogniteClient
5
5
  from industrial_model.cognite_adapters import CogniteAdapter
6
6
  from industrial_model.config import DataModelId
7
7
  from industrial_model.models import (
8
- AggregationResult,
9
8
  EdgeContainer,
10
9
  PaginatedResult,
10
+ TAggregatedViewInstance,
11
11
  TViewInstance,
12
12
  TWritableViewInstance,
13
13
  ValidationMode,
@@ -49,9 +49,11 @@ class Engine:
49
49
  return self._validate_data(statement.entity, data, validation_mode)
50
50
 
51
51
  def aggregate(
52
- self, statement: AggregationStatement[TViewInstance]
53
- ) -> list[AggregationResult]:
54
- return self._cognite_adapter.aggregate(statement)
52
+ self, statement: AggregationStatement[TAggregatedViewInstance]
53
+ ) -> list[TAggregatedViewInstance]:
54
+ data = self._cognite_adapter.aggregate(statement)
55
+
56
+ return [statement.entity.model_validate(item) for item in data]
55
57
 
56
58
  def upsert(
57
59
  self, entries: list[TWritableViewInstance], replace: bool = False
@@ -1,9 +1,10 @@
1
1
  from .base import RootModel
2
2
  from .entities import (
3
- AggregationResult,
3
+ AggregatedViewInstance,
4
4
  EdgeContainer,
5
5
  InstanceId,
6
6
  PaginatedResult,
7
+ TAggregatedViewInstance,
7
8
  TViewInstance,
8
9
  TWritableViewInstance,
9
10
  ValidationMode,
@@ -14,10 +15,11 @@ from .entities import (
14
15
  from .schemas import get_parent_and_children_nodes, get_schema_properties
15
16
 
16
17
  __all__ = [
17
- "AggregationResult",
18
+ "AggregatedViewInstance",
18
19
  "RootModel",
19
20
  "EdgeContainer",
20
21
  "InstanceId",
22
+ "TAggregatedViewInstance",
21
23
  "TViewInstance",
22
24
  "TWritableViewInstance",
23
25
  "ViewInstance",
@@ -44,3 +44,14 @@ class RootModel(BaseModel):
44
44
  populate_by_name=True,
45
45
  from_attributes=True,
46
46
  )
47
+
48
+ def get_field_name(self, field_name_or_alias: str) -> str | None:
49
+ entry = self.__class__.model_fields.get(field_name_or_alias)
50
+ if entry:
51
+ return field_name_or_alias
52
+
53
+ for key, field_info in self.__class__.model_fields.items():
54
+ if field_info.alias == field_name_or_alias:
55
+ return key
56
+
57
+ return None
@@ -56,17 +56,6 @@ class ViewInstance(InstanceId, metaclass=DBModelMetaclass):
56
56
  def get_view_external_id(cls) -> str:
57
57
  return cls.view_config.get("view_external_id") or cls.__name__
58
58
 
59
- def get_field_name(self, field_name_or_alias: str) -> str | None:
60
- entry = self.__class__.model_fields.get(field_name_or_alias)
61
- if entry:
62
- return field_name_or_alias
63
-
64
- for key, field_info in self.__class__.model_fields.items():
65
- if field_info.alias == field_name_or_alias:
66
- return key
67
-
68
- return None
69
-
70
59
 
71
60
  class WritableViewInstance(ViewInstance):
72
61
  @abstractmethod
@@ -78,10 +67,33 @@ class WritableViewInstance(ViewInstance):
78
67
  )
79
68
 
80
69
 
70
+ class AggregatedViewInstance(RootModel, metaclass=DBModelMetaclass):
71
+ view_config: ClassVar[ViewInstanceConfig] = ViewInstanceConfig()
72
+
73
+ value: float
74
+
75
+ @classmethod
76
+ def get_view_external_id(cls) -> str:
77
+ return cls.view_config.get("view_external_id") or cls.__name__
78
+
79
+ @classmethod
80
+ def get_group_by_fields(cls) -> list[str]:
81
+ group_by_fields: set[str] = set()
82
+ for key, field_info in cls.model_fields.items():
83
+ if key == "value":
84
+ continue
85
+ group_by_fields.add(field_info.alias or key)
86
+
87
+ return list(group_by_fields)
88
+
89
+
81
90
  TViewInstance = TypeVar("TViewInstance", bound=ViewInstance)
82
91
  TWritableViewInstance = TypeVar(
83
92
  "TWritableViewInstance", bound=WritableViewInstance
84
93
  )
94
+ TAggregatedViewInstance = TypeVar(
95
+ "TAggregatedViewInstance", bound=AggregatedViewInstance
96
+ )
85
97
 
86
98
 
87
99
  class PaginatedResult(RootModel, Generic[TViewInstance]):
@@ -90,10 +102,4 @@ class PaginatedResult(RootModel, Generic[TViewInstance]):
90
102
  next_cursor: str | None
91
103
 
92
104
 
93
- class AggregationResult(RootModel):
94
- group: dict[str, str | int | float | bool | InstanceId] | None
95
- value: float
96
- aggregate: str
97
-
98
-
99
105
  ValidationMode = Literal["raiseOnError", "ignoreOnError"]
@@ -63,30 +63,24 @@ class Statement(Generic[T]):
63
63
  return self
64
64
 
65
65
 
66
+ AggregateTypes = Literal["count", "avg", "min", "max", "sum"]
67
+
68
+
66
69
  @dataclass
67
70
  class AggregationStatement(Generic[T]):
68
- aggregate_: Literal["count"] = field(init=False, default="count")
71
+ entity: type[T] = field(init=True)
72
+ aggregate: AggregateTypes = field(init=True)
73
+
69
74
  aggregation_property: Column = field(
70
75
  init=False, default=Column("externalId")
71
76
  )
72
-
73
- entity: type[T] = field(init=True)
74
- group_by_columns: list[Column] = field(init=False, default_factory=list)
75
77
  where_clauses: list[Expression] = field(init=False, default_factory=list)
76
78
  limit_: int = field(init=False, default=-1)
77
79
 
78
- def aggregate(self, aggregates: Literal["count"]) -> Self:
79
- self.aggregate_ = aggregates
80
- return self
81
-
82
80
  def aggregate_by(self, property: str | Column | Any) -> Self:
83
81
  self.aggregation_property = _create_column(property)
84
82
  return self
85
83
 
86
- def group_by(self, *property: str | Column | Any) -> Self:
87
- self.group_by_columns.extend(_create_column(p) for p in property)
88
- return self
89
-
90
84
  def where(self, *expressions: bool | Expression) -> Self:
91
85
  for expression in expressions:
92
86
  assert isinstance(expression, Expression)
@@ -102,8 +96,11 @@ def select(entity: type[T]) -> Statement[T]:
102
96
  return Statement(entity)
103
97
 
104
98
 
105
- def aggregate(entity: type[T]) -> AggregationStatement[T]:
106
- return AggregationStatement(entity)
99
+ def aggregate(
100
+ entity: type[T],
101
+ aggregate: AggregateTypes = "count",
102
+ ) -> AggregationStatement[T]:
103
+ return AggregationStatement(entity=entity, aggregate=aggregate)
107
104
 
108
105
 
109
106
  __all__ = [
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "industrial-model"
3
- version = "0.1.12"
3
+ version = "0.1.13"
4
4
  description = "Industrial Model ORM"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -52,6 +52,15 @@ class Event(ViewInstance):
52
52
  ]
53
53
 
54
54
 
55
+ class Msdp(ViewInstance):
56
+ view_config = ViewInstanceConfig(
57
+ view_external_id="OEEMSDP",
58
+ instance_spaces_prefix="OEE-",
59
+ )
60
+
61
+ effective_date: datetime.date
62
+
63
+
55
64
  class WritableEvent(WritableViewInstance):
56
65
  view_config = ViewInstanceConfig(
57
66
  view_external_id="OEEEvent",
@@ -1,10 +1,10 @@
1
1
  import datetime
2
2
  import json
3
3
 
4
- from industrial_model import aggregate, col, select
4
+ from industrial_model import col, select
5
5
 
6
6
  from .hubs import generate_engine
7
- from .models import DescribableEntity, Event
7
+ from .models import DescribableEntity, Event, Msdp
8
8
 
9
9
  if __name__ == "__main__":
10
10
  adapter = generate_engine()
@@ -26,6 +26,17 @@ if __name__ == "__main__":
26
26
  for item in adapter.query_all_pages(statement)
27
27
  ]
28
28
  print(len(result))
29
- json.dump(result, open("entities.json", "w"), indent=2)
29
+ json.dump(result, open("events.json", "w"), indent=2)
30
30
 
31
- print(adapter.aggregate(aggregate(Event).group_by(Event.space)))
31
+ statement_msdp = (
32
+ select(Msdp)
33
+ .limit(2500)
34
+ .where(Msdp.effective_date >= datetime.date(2022, 5, 1))
35
+ )
36
+
37
+ result_msdp = [
38
+ item.model_dump(mode="json")
39
+ for item in adapter.query_all_pages(statement_msdp)
40
+ ]
41
+ print(len(result_msdp))
42
+ json.dump(result_msdp, open("msdp.json", "w"), indent=2)
@@ -0,0 +1,19 @@
1
+ from industrial_model import (
2
+ AggregatedViewInstance,
3
+ ViewInstanceConfig,
4
+ aggregate,
5
+ )
6
+
7
+ from .hubs import generate_engine
8
+
9
+ if __name__ == "__main__":
10
+ adapter = generate_engine()
11
+
12
+ default_config = ViewInstanceConfig(view_external_id="OEEEvent")
13
+
14
+ class AggregatedEvent(AggregatedViewInstance):
15
+ view_config = default_config
16
+ event_definition: str
17
+
18
+ aggregate_result = adapter.aggregate(aggregate(AggregatedEvent, "count"))
19
+ print(aggregate_result)
@@ -215,7 +215,7 @@ wheels = [
215
215
 
216
216
  [[package]]
217
217
  name = "industrial-model"
218
- version = "0.1.12"
218
+ version = "0.1.13"
219
219
  source = { editable = "." }
220
220
  dependencies = [
221
221
  { name = "anyio" },