statikk 0.1.5__tar.gz → 0.1.7__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 (43) hide show
  1. {statikk-0.1.5 → statikk-0.1.7}/PKG-INFO +1 -1
  2. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/engine.py +5 -1
  3. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/models.py +23 -3
  4. {statikk-0.1.5 → statikk-0.1.7}/src/statikk.egg-info/PKG-INFO +1 -1
  5. {statikk-0.1.5 → statikk-0.1.7}/tests/test_engine.py +8 -3
  6. {statikk-0.1.5 → statikk-0.1.7}/tests/test_models.py +49 -0
  7. {statikk-0.1.5 → statikk-0.1.7}/.coveragerc +0 -0
  8. {statikk-0.1.5 → statikk-0.1.7}/.gitignore +0 -0
  9. {statikk-0.1.5 → statikk-0.1.7}/.readthedocs.yml +0 -0
  10. {statikk-0.1.5 → statikk-0.1.7}/AUTHORS.rst +0 -0
  11. {statikk-0.1.5 → statikk-0.1.7}/CHANGELOG.rst +0 -0
  12. {statikk-0.1.5 → statikk-0.1.7}/CONTRIBUTING.rst +0 -0
  13. {statikk-0.1.5 → statikk-0.1.7}/LICENSE.txt +0 -0
  14. {statikk-0.1.5 → statikk-0.1.7}/README.rst +0 -0
  15. {statikk-0.1.5 → statikk-0.1.7}/assets/favicon.png +0 -0
  16. {statikk-0.1.5 → statikk-0.1.7}/assets/logo.png +0 -0
  17. {statikk-0.1.5 → statikk-0.1.7}/docs/Makefile +0 -0
  18. {statikk-0.1.5 → statikk-0.1.7}/docs/_static/.gitignore +0 -0
  19. {statikk-0.1.5 → statikk-0.1.7}/docs/authors.rst +0 -0
  20. {statikk-0.1.5 → statikk-0.1.7}/docs/changelog.rst +0 -0
  21. {statikk-0.1.5 → statikk-0.1.7}/docs/conf.py +0 -0
  22. {statikk-0.1.5 → statikk-0.1.7}/docs/contributing.rst +0 -0
  23. {statikk-0.1.5 → statikk-0.1.7}/docs/index.rst +0 -0
  24. {statikk-0.1.5 → statikk-0.1.7}/docs/license.rst +0 -0
  25. {statikk-0.1.5 → statikk-0.1.7}/docs/readme.rst +0 -0
  26. {statikk-0.1.5 → statikk-0.1.7}/docs/requirements.txt +0 -0
  27. {statikk-0.1.5 → statikk-0.1.7}/docs/usage.rst +0 -0
  28. {statikk-0.1.5 → statikk-0.1.7}/pyproject.toml +0 -0
  29. {statikk-0.1.5 → statikk-0.1.7}/setup.cfg +0 -0
  30. {statikk-0.1.5 → statikk-0.1.7}/setup.py +0 -0
  31. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/__init__.py +0 -0
  32. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/conditions.py +0 -0
  33. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/expressions.py +0 -0
  34. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/fields.py +0 -0
  35. {statikk-0.1.5 → statikk-0.1.7}/src/statikk/typing.py +0 -0
  36. {statikk-0.1.5 → statikk-0.1.7}/src/statikk.egg-info/SOURCES.txt +0 -0
  37. {statikk-0.1.5 → statikk-0.1.7}/src/statikk.egg-info/dependency_links.txt +0 -0
  38. {statikk-0.1.5 → statikk-0.1.7}/src/statikk.egg-info/not-zip-safe +0 -0
  39. {statikk-0.1.5 → statikk-0.1.7}/src/statikk.egg-info/requires.txt +0 -0
  40. {statikk-0.1.5 → statikk-0.1.7}/src/statikk.egg-info/top_level.txt +0 -0
  41. {statikk-0.1.5 → statikk-0.1.7}/tests/conftest.py +0 -0
  42. {statikk-0.1.5 → statikk-0.1.7}/tests/test_expressions.py +0 -0
  43. {statikk-0.1.5 → statikk-0.1.7}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: statikk
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: statikk is a single table application (STA) library for DynamoDb.
5
5
  Home-page: https://github.com/terinia/statikk
6
6
  Author: Balint Biro
@@ -232,9 +232,13 @@ class Table:
232
232
 
233
233
  Returns the enriched database model instance.
234
234
  """
235
+
235
236
  with self.batch_write() as batch:
236
237
  for item in model.split_to_simple_objects():
237
- batch.put(item)
238
+ if item._should_delete:
239
+ batch.delete(item)
240
+ else:
241
+ batch.put(item)
238
242
 
239
243
  def update_item(
240
244
  self,
@@ -67,16 +67,18 @@ class TrackingMixin:
67
67
 
68
68
  def _recursive_hash(self) -> int:
69
69
  """
70
- Compute a hash value for the model, ignoring nested DatabaseModel instances.
70
+ Compute a hash value for the model, ignoring specified fields and nested DatabaseModel instances.
71
71
 
72
- This ensures that changes to child models don't affect the parent's hash.
72
+ This ensures that changes to ignored fields or child models don't affect the parent's hash.
73
73
 
74
74
  Returns:
75
- A hash value representing the model's non-model fields.
75
+ A hash value representing the model's non-ignored fields.
76
76
  """
77
77
  if not self.should_track:
78
78
  return 0
79
79
 
80
+ ignored_fields = self.ignore_tracking_fields()
81
+
80
82
  values = []
81
83
  for field_name in self.model_fields:
82
84
  if not hasattr(self, field_name):
@@ -85,6 +87,9 @@ class TrackingMixin:
85
87
  if field_name.startswith("_"):
86
88
  continue
87
89
 
90
+ if field_name in ignored_fields:
91
+ continue
92
+
88
93
  value = getattr(self, field_name)
89
94
 
90
95
  if hasattr(value, "__class__") and issubclass(value.__class__, DatabaseModel):
@@ -141,11 +146,23 @@ class TrackingMixin:
141
146
 
142
147
  return True
143
148
 
149
+ def ignore_tracking_fields(self) -> set:
150
+ """
151
+ Override this method to specify fields to ignore when tracking changes.
152
+
153
+ Returns:
154
+ A set specifying fields to ignore.
155
+ Example:
156
+ {"field1", "field2"}
157
+ """
158
+ return {}
159
+
144
160
 
145
161
  class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
146
162
  id: str = Field(default_factory=lambda: str(uuid4()))
147
163
  _parent: Optional[DatabaseModel] = None
148
164
  _model_types_in_hierarchy: dict[str, Type[DatabaseModel]] = {}
165
+ _should_delete: bool = False
149
166
 
150
167
  @classmethod
151
168
  def type(cls) -> str:
@@ -240,6 +257,9 @@ class DatabaseModel(BaseModel, TrackingMixin, extra=Extra.allow):
240
257
  return self._parent.should_write_to_database()
241
258
  return True
242
259
 
260
+ def mark_for_delete(self):
261
+ self._should_delete = True
262
+
243
263
  @classmethod
244
264
  def scan(
245
265
  cls,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: statikk
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: statikk is a single table application (STA) library for DynamoDb.
5
5
  Home-page: https://github.com/terinia/statikk
6
6
  Author: Balint Biro
@@ -788,7 +788,7 @@ def test_nested_hierarchies():
788
788
 
789
789
  class DoublyNestedModel(DatabaseModel):
790
790
  bar: str
791
- items: list[TriplyNested]
791
+ items: list[TriplyNested] = []
792
792
 
793
793
  @classmethod
794
794
  def index_definitions(cls) -> dict[str, IndexFieldConfig]:
@@ -803,7 +803,7 @@ def test_nested_hierarchies():
803
803
 
804
804
  class NestedModel(DatabaseModel):
805
805
  foo: str
806
- doubly_nested: list[DoublyNestedModel]
806
+ doubly_nested: list[DoublyNestedModel] = []
807
807
 
808
808
  @classmethod
809
809
  def index_definitions(cls) -> dict[str, IndexFieldConfig]:
@@ -836,7 +836,8 @@ def test_nested_hierarchies():
836
836
  models=[ModelHierarchy, NestedModel, DoublyNestedModel, TriplyNested],
837
837
  )
838
838
  _create_dynamodb_table(table)
839
- doubly_nested = DoublyNestedModel(bar="bar", items=[TriplyNested(faz="faz")])
839
+ triple_nested_model = TriplyNested(faz="faz")
840
+ doubly_nested = DoublyNestedModel(bar="bar", items=[triple_nested_model])
840
841
  double_nested_no_write = DoublyNestedModel(bar="far", items=[TriplyNested(faz="faz")])
841
842
  nested = NestedModel(foo="foo", doubly_nested=[doubly_nested, double_nested_no_write])
842
843
  model_hierarchy = ModelHierarchy(foo_id="foo_id", state="state", nested=nested)
@@ -850,5 +851,9 @@ def test_nested_hierarchies():
850
851
  assert hierarchy.nested.doubly_nested[0].gsi_pk == "foo_id"
851
852
  assert hierarchy.nested.doubly_nested[0].gsi_sk == "ModelHierarchy|state|NestedModel|foo|DoublyNestedModel|bar"
852
853
  assert hierarchy.nested.doubly_nested[0].items[0].gsi_pk == "foo_id"
854
+ hierarchy.nested.doubly_nested[0].items[0].mark_for_delete()
855
+ hierarchy.save()
856
+ hierarchy = ModelHierarchy.query_hierarchy(hash_key=Equals("foo_id"))
857
+ assert len(hierarchy.nested.doubly_nested[0].items) == 0
853
858
  hierarchy.delete()
854
859
  assert list(table.scan()) == []
@@ -106,3 +106,52 @@ def test_tracking_disabled():
106
106
  assert my_database_model.was_modified is True # untracked models should always be marked as modified
107
107
  my_database_model.foo = "bar"
108
108
  assert my_database_model.was_modified is True
109
+
110
+
111
+ def test_testing_configuration():
112
+ class MyOtherNestedDatabaseModel(DatabaseModel):
113
+ baz: str = "baz"
114
+ qux: str = "qux"
115
+ xax: str = "xax"
116
+
117
+ @classmethod
118
+ def is_nested(cls) -> bool:
119
+ return True
120
+
121
+ def ignore_tracking_fields(self) -> set:
122
+ return {"baz", "qux"}
123
+
124
+ class MyNestedDatabaseModel(DatabaseModel):
125
+ bar: str = "bar"
126
+ other_nested: MyOtherNestedDatabaseModel
127
+
128
+ @classmethod
129
+ def is_nested(cls) -> bool:
130
+ return True
131
+
132
+ class MyDatabaseModel(DatabaseModel):
133
+ foo: str = "foo"
134
+ nested: MyNestedDatabaseModel
135
+
136
+ @property
137
+ def should_track(self) -> bool:
138
+ return True
139
+
140
+ def ignore_tracking_fields(self) -> set:
141
+ return {"foo"}
142
+
143
+ my_database_model = MyDatabaseModel(
144
+ foo="foo",
145
+ nested=MyNestedDatabaseModel(
146
+ bar="bar", other_nested=MyOtherNestedDatabaseModel(baz="baz", qux="qux", xax="xax")
147
+ ),
148
+ )
149
+ assert my_database_model.was_modified is False
150
+ my_database_model.foo = "bar"
151
+ assert my_database_model.was_modified is False
152
+ my_database_model.nested.other_nested.baz = "qux"
153
+ assert my_database_model.nested.other_nested.was_modified is False
154
+ my_database_model.nested.other_nested.qux = "xax"
155
+ assert my_database_model.nested.other_nested.was_modified is False
156
+ my_database_model.nested.bar = "baz"
157
+ assert my_database_model.nested.was_modified is True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes