statikk 0.1.0__py3-none-any.whl → 0.1.2__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 +8 -9
- statikk/models.py +23 -12
- statikk/typing.py +3 -0
- {statikk-0.1.0.dist-info → statikk-0.1.2.dist-info}/METADATA +1 -1
- statikk-0.1.2.dist-info/RECORD +12 -0
- statikk-0.1.0.dist-info/RECORD +0 -11
- {statikk-0.1.0.dist-info → statikk-0.1.2.dist-info}/LICENSE.txt +0 -0
- {statikk-0.1.0.dist-info → statikk-0.1.2.dist-info}/WHEEL +0 -0
- {statikk-0.1.0.dist-info → statikk-0.1.2.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)]
|
@@ -548,7 +547,7 @@ class Table:
|
|
548
547
|
sort_key_values.append(model.type())
|
549
548
|
for sort_key_field in sort_key_fields:
|
550
549
|
if sort_key_field in model.model_fields.keys():
|
551
|
-
sort_key_values.append(getattr(model, sort_key_field))
|
550
|
+
sort_key_values.append(self._serialize_value(getattr(model, sort_key_field)))
|
552
551
|
|
553
552
|
return self.delimiter.join(sort_key_values)
|
554
553
|
|
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,6 +56,10 @@ class IndexFieldConfig(BaseModel):
|
|
55
56
|
class TrackingMixin:
|
56
57
|
_original_hash: int = Field(exclude=True)
|
57
58
|
|
59
|
+
@classmethod
|
60
|
+
def should_track(cls) -> bool:
|
61
|
+
return True
|
62
|
+
|
58
63
|
def __init__(self):
|
59
64
|
self._original_hash = self._recursive_hash()
|
60
65
|
|
@@ -99,7 +104,9 @@ class TrackingMixin:
|
|
99
104
|
if contains_model:
|
100
105
|
continue
|
101
106
|
|
102
|
-
|
107
|
+
hashed_value = self._make_hashable(value)
|
108
|
+
if hashed_value is not None:
|
109
|
+
values.append(hashed_value)
|
103
110
|
|
104
111
|
return hash(tuple(values))
|
105
112
|
|
@@ -110,20 +117,24 @@ class TrackingMixin:
|
|
110
117
|
return tuple(self._make_hashable(item) for item in value)
|
111
118
|
elif isinstance(value, dict):
|
112
119
|
return tuple((self._make_hashable(k), self._make_hashable(v)) for k, v in sorted(value.items()))
|
113
|
-
elif isinstance(value, BaseModel):
|
114
|
-
return value._recursive_hash()
|
120
|
+
elif isinstance(value, BaseModel) and hasattr(value, "_recursive_hash"):
|
121
|
+
return value._recursive_hash()
|
115
122
|
else:
|
116
123
|
try:
|
117
124
|
return hash(value)
|
118
|
-
except
|
125
|
+
except TypeError:
|
119
126
|
logger.warning(
|
120
127
|
f"{type(value)} is unhashable, tracking will not work. Consider implementing the TrackingMixin for this type."
|
121
128
|
)
|
129
|
+
return None
|
122
130
|
return value
|
123
131
|
|
124
132
|
@property
|
125
133
|
def was_modified(self) -> bool:
|
126
|
-
|
134
|
+
if self.should_track():
|
135
|
+
return self._recursive_hash() != self._original_hash
|
136
|
+
|
137
|
+
return True
|
127
138
|
|
128
139
|
|
129
140
|
class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
@@ -157,12 +168,12 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
157
168
|
|
158
169
|
@classmethod
|
159
170
|
def query(
|
160
|
-
cls,
|
171
|
+
cls: Type[T],
|
161
172
|
hash_key: Condition,
|
162
173
|
range_key: Optional[Condition] = None,
|
163
174
|
filter_condition: Optional[ComparisonCondition] = None,
|
164
175
|
index_name: Optional[str] = None,
|
165
|
-
):
|
176
|
+
) -> T:
|
166
177
|
return cls._table.query_index(
|
167
178
|
hash_key=hash_key,
|
168
179
|
model_class=cls,
|
@@ -173,12 +184,12 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
173
184
|
|
174
185
|
@classmethod
|
175
186
|
def query_hierarchy(
|
176
|
-
cls,
|
187
|
+
cls: Type[T],
|
177
188
|
hash_key: Union[Condition | str],
|
178
189
|
range_key: Optional[Condition] = None,
|
179
190
|
filter_condition: Optional[ComparisonCondition] = None,
|
180
191
|
index_name: Optional[str] = None,
|
181
|
-
) ->
|
192
|
+
) -> T:
|
182
193
|
return cls._table.query_hierarchy(
|
183
194
|
hash_key=hash_key,
|
184
195
|
model_class=cls,
|
@@ -212,11 +223,11 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
212
223
|
)
|
213
224
|
|
214
225
|
@classmethod
|
215
|
-
def get(cls, id: str, sort_key: Optional[str] = None, consistent_read: bool = False):
|
226
|
+
def get(cls: Type[T], id: str, sort_key: Optional[str] = None, consistent_read: bool = False) -> T:
|
216
227
|
return cls._table.get_item(id=id, model_class=cls, sort_key=sort_key, consistent_read=consistent_read)
|
217
228
|
|
218
229
|
@classmethod
|
219
|
-
def batch_get(cls, ids: List[str], batch_size: int = 100):
|
230
|
+
def batch_get(cls: Type[T], ids: List[str], batch_size: int = 100) -> list[T]:
|
220
231
|
return cls._table.batch_get_items(ids=ids, model_class=cls, batch_size=batch_size)
|
221
232
|
|
222
233
|
def should_write_to_database(self) -> bool:
|
@@ -229,7 +240,7 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
|
|
229
240
|
cls,
|
230
241
|
filter_condition: Optional[ComparisonCondition] = None,
|
231
242
|
consistent_read: bool = False,
|
232
|
-
):
|
243
|
+
) -> list[DatabaseModel]:
|
233
244
|
return cls._table.scan(filter_condition=filter_condition)
|
234
245
|
|
235
246
|
@model_serializer(mode="wrap")
|
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=rekTKPnN-I3oBOTzqkAy4FmSnaXI-woQNyG3rG85en8,13155
|
7
|
+
statikk/typing.py,sha256=qfpegORcdODuILK3gvuD4SdcZA1a7Myn0yvscOLPHOM,68
|
8
|
+
statikk-0.1.2.dist-info/LICENSE.txt,sha256=uSH_2Hpb2Bigy5_HhBliN2fZbBU64G3ERM5zzhKPUEE,1078
|
9
|
+
statikk-0.1.2.dist-info/METADATA,sha256=7IOtn9UQIVO-Iy0jJKooQrtzbtSJRq90Q_Z0wKg05-Y,3160
|
10
|
+
statikk-0.1.2.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
11
|
+
statikk-0.1.2.dist-info/top_level.txt,sha256=etKmBbjzIlLpSefXoiOfhWGEgvqUEALaFwCjFDBD9YI,8
|
12
|
+
statikk-0.1.2.dist-info/RECORD,,
|
statikk-0.1.0.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=GCcqowgJa041Oo22sarSqDUQRWS4GbwHSNz_WGmcpNM,30855
|
4
|
-
statikk/expressions.py,sha256=mF6Hmj3Kmj6KKXTymeTHSepVA7rhiSINpFgSAPeBTRY,12210
|
5
|
-
statikk/fields.py,sha256=LkMP5NnX7WS0HSLxI3Q-dMOrfaJ0SD7SayZxJU5Acgg,86
|
6
|
-
statikk/models.py,sha256=S5KdjNH0ufGn7iW4ZTVMXv1e177U95C28mbUlwDax_k,12831
|
7
|
-
statikk-0.1.0.dist-info/LICENSE.txt,sha256=uSH_2Hpb2Bigy5_HhBliN2fZbBU64G3ERM5zzhKPUEE,1078
|
8
|
-
statikk-0.1.0.dist-info/METADATA,sha256=Aqf0Od-2YmGbkQRqX36IhwPPzx-r5Wjr2ipe5dBcj7o,3160
|
9
|
-
statikk-0.1.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
10
|
-
statikk-0.1.0.dist-info/top_level.txt,sha256=etKmBbjzIlLpSefXoiOfhWGEgvqUEALaFwCjFDBD9YI,8
|
11
|
-
statikk-0.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|