statikk 0.1.1__py3-none-any.whl → 0.1.3__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.
- statikk/engine.py +7 -8
- statikk/models.py +24 -10
- statikk/typing.py +3 -0
- {statikk-0.1.1.dist-info → statikk-0.1.3.dist-info}/METADATA +1 -1
- statikk-0.1.3.dist-info/RECORD +12 -0
- statikk-0.1.1.dist-info/RECORD +0 -11
- {statikk-0.1.1.dist-info → statikk-0.1.3.dist-info}/LICENSE.txt +0 -0
- {statikk-0.1.1.dist-info → statikk-0.1.3.dist-info}/WHEEL +0 -0
- {statikk-0.1.1.dist-info → statikk-0.1.3.dist-info}/top_level.txt +0 -0
statikk/engine.py
CHANGED
@@ -8,6 +8,7 @@ from pydantic.fields import FieldInfo
|
|
8
8
|
from boto3.dynamodb.conditions import ComparisonCondition, Key
|
9
9
|
from boto3.dynamodb.types import TypeDeserializer, Decimal
|
10
10
|
|
11
|
+
from statikk.typing import T
|
11
12
|
from statikk.conditions import Condition, Equals, BeginsWith
|
12
13
|
from statikk.expressions import UpdateExpressionBuilder
|
13
14
|
from statikk.models import (
|
@@ -170,10 +171,10 @@ class Table:
|
|
170
171
|
def get_item(
|
171
172
|
self,
|
172
173
|
id: str,
|
173
|
-
model_class: Type[
|
174
|
+
model_class: Type[T],
|
174
175
|
sort_key: Optional[Any] = None,
|
175
176
|
consistent_read: bool = False,
|
176
|
-
):
|
177
|
+
) -> T:
|
177
178
|
"""
|
178
179
|
Returns an item from the database by id, using the partition key of the table.
|
179
180
|
:param id: The id of the item to retrieve.
|
@@ -331,11 +332,11 @@ class Table:
|
|
331
332
|
def query_index(
|
332
333
|
self,
|
333
334
|
hash_key: Union[Condition | str],
|
334
|
-
model_class: Type[
|
335
|
+
model_class: Type[T],
|
335
336
|
range_key: Optional[Condition] = None,
|
336
337
|
filter_condition: Optional[ComparisonCondition] = None,
|
337
338
|
index_name: Optional[str] = None,
|
338
|
-
):
|
339
|
+
) -> list[T]:
|
339
340
|
"""
|
340
341
|
Queries the database using the provided hash key and range key conditions. A filter condition can also be provided
|
341
342
|
using the filter_condition parameter. The method returns a list of items matching the query, deserialized into the
|
@@ -397,7 +398,7 @@ class Table:
|
|
397
398
|
self,
|
398
399
|
filter_condition: Optional[ComparisonCondition] = None,
|
399
400
|
consistent_read: bool = False,
|
400
|
-
):
|
401
|
+
) -> list[DatabaseModel]:
|
401
402
|
"""
|
402
403
|
Scans the database for items matching the provided filter condition. The method returns a list of items matching
|
403
404
|
the query, deserialized into the provided model_class parameter.
|
@@ -421,9 +422,7 @@ class Table:
|
|
421
422
|
deserializer = TypeDeserializer()
|
422
423
|
return {k: deserializer.deserialize(v) for k, v in item.items()}
|
423
424
|
|
424
|
-
def batch_get_items(
|
425
|
-
self, ids: List[str], model_class: Type[DatabaseModel], batch_size: int = 100
|
426
|
-
) -> List[DatabaseModel]:
|
425
|
+
def batch_get_items(self, ids: List[str], model_class: Type[T], batch_size: int = 100) -> list[T]:
|
427
426
|
dynamodb = self._dynamodb_client()
|
428
427
|
|
429
428
|
id_batches = [ids[i : i + batch_size] for i in range(0, len(ids), batch_size)]
|
statikk/models.py
CHANGED
@@ -4,6 +4,7 @@ import typing
|
|
4
4
|
import logging
|
5
5
|
from uuid import uuid4
|
6
6
|
from typing import Optional, List, Any, Set, Type
|
7
|
+
from statikk.typing import T
|
7
8
|
|
8
9
|
from boto3.dynamodb.conditions import ComparisonCondition
|
9
10
|
from pydantic import BaseModel, model_serializer, model_validator, Field, Extra
|
@@ -55,7 +56,13 @@ class IndexFieldConfig(BaseModel):
|
|
55
56
|
class TrackingMixin:
|
56
57
|
_original_hash: int = Field(exclude=True)
|
57
58
|
|
58
|
-
|
59
|
+
@property
|
60
|
+
def should_track(self) -> bool:
|
61
|
+
if self._parent is not None:
|
62
|
+
return self._parent.should_track
|
63
|
+
return False
|
64
|
+
|
65
|
+
def init_tracking(self):
|
59
66
|
self._original_hash = self._recursive_hash()
|
60
67
|
|
61
68
|
def _recursive_hash(self) -> int:
|
@@ -67,6 +74,9 @@ class TrackingMixin:
|
|
67
74
|
Returns:
|
68
75
|
A hash value representing the model's non-model fields.
|
69
76
|
"""
|
77
|
+
if not self.should_track:
|
78
|
+
return 0
|
79
|
+
|
70
80
|
values = []
|
71
81
|
for field_name in self.model_fields:
|
72
82
|
if not hasattr(self, field_name):
|
@@ -126,7 +136,10 @@ class TrackingMixin:
|
|
126
136
|
|
127
137
|
@property
|
128
138
|
def was_modified(self) -> bool:
|
129
|
-
|
139
|
+
if self.should_track:
|
140
|
+
return self._recursive_hash() != self._original_hash
|
141
|
+
|
142
|
+
return True
|
130
143
|
|
131
144
|
|
132
145
|
class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
@@ -160,12 +173,12 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
160
173
|
|
161
174
|
@classmethod
|
162
175
|
def query(
|
163
|
-
cls,
|
176
|
+
cls: Type[T],
|
164
177
|
hash_key: Condition,
|
165
178
|
range_key: Optional[Condition] = None,
|
166
179
|
filter_condition: Optional[ComparisonCondition] = None,
|
167
180
|
index_name: Optional[str] = None,
|
168
|
-
):
|
181
|
+
) -> T:
|
169
182
|
return cls._table.query_index(
|
170
183
|
hash_key=hash_key,
|
171
184
|
model_class=cls,
|
@@ -176,12 +189,12 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
176
189
|
|
177
190
|
@classmethod
|
178
191
|
def query_hierarchy(
|
179
|
-
cls,
|
192
|
+
cls: Type[T],
|
180
193
|
hash_key: Union[Condition | str],
|
181
194
|
range_key: Optional[Condition] = None,
|
182
195
|
filter_condition: Optional[ComparisonCondition] = None,
|
183
196
|
index_name: Optional[str] = None,
|
184
|
-
) ->
|
197
|
+
) -> T:
|
185
198
|
return cls._table.query_hierarchy(
|
186
199
|
hash_key=hash_key,
|
187
200
|
model_class=cls,
|
@@ -215,11 +228,11 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
215
228
|
)
|
216
229
|
|
217
230
|
@classmethod
|
218
|
-
def get(cls, id: str, sort_key: Optional[str] = None, consistent_read: bool = False):
|
231
|
+
def get(cls: Type[T], id: str, sort_key: Optional[str] = None, consistent_read: bool = False) -> T:
|
219
232
|
return cls._table.get_item(id=id, model_class=cls, sort_key=sort_key, consistent_read=consistent_read)
|
220
233
|
|
221
234
|
@classmethod
|
222
|
-
def batch_get(cls, ids: List[str], batch_size: int = 100):
|
235
|
+
def batch_get(cls: Type[T], ids: List[str], batch_size: int = 100) -> list[T]:
|
223
236
|
return cls._table.batch_get_items(ids=ids, model_class=cls, batch_size=batch_size)
|
224
237
|
|
225
238
|
def should_write_to_database(self) -> bool:
|
@@ -232,7 +245,7 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
232
245
|
cls,
|
233
246
|
filter_condition: Optional[ComparisonCondition] = None,
|
234
247
|
consistent_read: bool = False,
|
235
|
-
):
|
248
|
+
) -> list[DatabaseModel]:
|
236
249
|
return cls._table.scan(filter_condition=filter_condition)
|
237
250
|
|
238
251
|
@model_serializer(mode="wrap")
|
@@ -245,10 +258,10 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
245
258
|
|
246
259
|
@model_validator(mode="after")
|
247
260
|
def initialize_tracking(self):
|
248
|
-
self._original_hash = self._recursive_hash()
|
249
261
|
self._model_types_in_hierarchy[self.type()] = type(self)
|
250
262
|
if not self.is_nested():
|
251
263
|
self._set_parent_references(self)
|
264
|
+
self.init_tracking()
|
252
265
|
|
253
266
|
return self
|
254
267
|
|
@@ -343,6 +356,7 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
343
356
|
field._parent = parent
|
344
357
|
root._model_types_in_hierarchy[field.type()] = type(field)
|
345
358
|
field._set_parent_references(root)
|
359
|
+
field.init_tracking()
|
346
360
|
|
347
361
|
def _set_parent_references(self, root: DatabaseModel):
|
348
362
|
for field_name, field_value in self:
|
statikk/typing.py
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
statikk/__init__.py,sha256=pH5i4Fj1tbXLqLtTVIdoojiplZssQn0nnud8-HXodRE,577
|
2
|
+
statikk/conditions.py,sha256=63FYMR-UUaE-ZJEb_8CU721CQTwhajq39-BbokmKeMA,2166
|
3
|
+
statikk/engine.py,sha256=hMA6V_aneWpJlCa4mogu6rE3-T7qwFuRGAkK-0nREj8,30884
|
4
|
+
statikk/expressions.py,sha256=mF6Hmj3Kmj6KKXTymeTHSepVA7rhiSINpFgSAPeBTRY,12210
|
5
|
+
statikk/fields.py,sha256=LkMP5NnX7WS0HSLxI3Q-dMOrfaJ0SD7SayZxJU5Acgg,86
|
6
|
+
statikk/models.py,sha256=GgEhoHhStykOtfPEgO5GdGITVEX0Kj26UnpVN8fDp3o,13301
|
7
|
+
statikk/typing.py,sha256=qfpegORcdODuILK3gvuD4SdcZA1a7Myn0yvscOLPHOM,68
|
8
|
+
statikk-0.1.3.dist-info/LICENSE.txt,sha256=uSH_2Hpb2Bigy5_HhBliN2fZbBU64G3ERM5zzhKPUEE,1078
|
9
|
+
statikk-0.1.3.dist-info/METADATA,sha256=5X1jmvD-a2OXeQwQeZo6AFUeqiAxDrNo1zBKL9Zs-KA,3160
|
10
|
+
statikk-0.1.3.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
11
|
+
statikk-0.1.3.dist-info/top_level.txt,sha256=etKmBbjzIlLpSefXoiOfhWGEgvqUEALaFwCjFDBD9YI,8
|
12
|
+
statikk-0.1.3.dist-info/RECORD,,
|
statikk-0.1.1.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
statikk/__init__.py,sha256=pH5i4Fj1tbXLqLtTVIdoojiplZssQn0nnud8-HXodRE,577
|
2
|
-
statikk/conditions.py,sha256=63FYMR-UUaE-ZJEb_8CU721CQTwhajq39-BbokmKeMA,2166
|
3
|
-
statikk/engine.py,sha256=ny15q1yLEJYTszxCaHxqdm7GRC3xsCZBtjPfNGHn0Dk,30878
|
4
|
-
statikk/expressions.py,sha256=mF6Hmj3Kmj6KKXTymeTHSepVA7rhiSINpFgSAPeBTRY,12210
|
5
|
-
statikk/fields.py,sha256=LkMP5NnX7WS0HSLxI3Q-dMOrfaJ0SD7SayZxJU5Acgg,86
|
6
|
-
statikk/models.py,sha256=6ssCECKFCHZwN_-LA-epHhqtVNJK0pt6PlIVj9UxKUI,12928
|
7
|
-
statikk-0.1.1.dist-info/LICENSE.txt,sha256=uSH_2Hpb2Bigy5_HhBliN2fZbBU64G3ERM5zzhKPUEE,1078
|
8
|
-
statikk-0.1.1.dist-info/METADATA,sha256=bfSuQ9QD8mDp_9CdmlgApWp0h-rlAhCsgO-ChPETOkQ,3160
|
9
|
-
statikk-0.1.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
10
|
-
statikk-0.1.1.dist-info/top_level.txt,sha256=etKmBbjzIlLpSefXoiOfhWGEgvqUEALaFwCjFDBD9YI,8
|
11
|
-
statikk-0.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|