From 456b2735fc93866fd580d0a714b3a1304c5e1d85 Mon Sep 17 00:00:00 2001 From: Stas Davydov Date: Fri, 5 Jul 2024 23:58:15 +0800 Subject: [PATCH] SQLite storage is added. Msgspec is supported. Documentation is updated --- README.md | 16 +++++++++++++--- pys/sqlite.py | 6 ++++-- setup.py | 2 +- tests/test_sample1.py | 21 +++++++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 52e3253..204c8e9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Python Object Storage -Simple JSON file storage for Python dataclasses and Pydantic models, thread and multiprocess safe. +Simple fast JSON file storage for Python dataclasses and Pydantic models, thread and multiprocess safe. ---- @@ -119,8 +119,11 @@ assert for_kids in leo_books ```python import pys -# Initialize storage -storage = pys.storage('.path-to-storage') +# Initialize default (file) storage +storage1 = pys.storage('.path-to-storage') + +# Initialize SQLite storage +storage2 = pys.sqlite_storage('path-to-storage.db') # Save a model with optional relation to other models storage.save(model, [related_model | (RelatedModelClass, related_model_id), ...]) @@ -133,10 +136,17 @@ storage.delete(ModelClass, model_id, [related_model | (RelatedModelClass, relate # List models by specified ModelClass with optional relation to other models storage.list(ModelClass, [related_model | (RelatedModelClass, related_model_id), ...]) + +# Destroy storage +storage.destroy() ``` ## Release Notes +### 0.0.4 +SQLite storage is added. +Support of `msqspec` JSON and structures is added. + ### 0.0.3 Benchmark is added, performance is improved. Fixed dependency set up. diff --git a/pys/sqlite.py b/pys/sqlite.py index fc67881..49f8ce6 100644 --- a/pys/sqlite.py +++ b/pys/sqlite.py @@ -93,13 +93,15 @@ def _save(self, model: StoredModel, prev=Related): prev_id, prev_cls.__name__ if prev else None,), ) - return self.con.total_changes + return model.__my_id__() def save(self, model: StoredModel, *related_model: Related) -> Any: prev_model = None + last_id = None for m in related_model + (model,): - self._save(m, prev=prev_model) + last_id = self._save(m, prev=prev_model) prev_model = m + return last_id def delete(self, model_class: Type[StoredModel], model_id: str, *related_model: Related) -> None: last_related = related_model[-1] if related_model else None diff --git a/setup.py b/setup.py index 9a36e3f..0c33e09 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ README = (HERE / "README.md").read_text() setup(name='pysdato', - version='0.0.3', + version='0.0.4', description='Simple JSON file storage for Python dataclasses and pydantic models, thread and multiprocess safe', long_description=README, long_description_content_type="text/markdown", diff --git a/tests/test_sample1.py b/tests/test_sample1.py index 8bd74db..e1c6e52 100644 --- a/tests/test_sample1.py +++ b/tests/test_sample1.py @@ -1,5 +1,7 @@ from dataclasses import dataclass +import msgspec + import pys from pys.pydantic import ModelWithID @@ -33,6 +35,25 @@ class Author: # Persist model Author leo = Author(name='Leo Tolstoy') leo_id = storage.save(leo) + assert leo_id + + # Load model Author by its ID and check it's the same + another_leo = storage.load(Author, leo_id) + assert another_leo.name == leo.name + + +def test_sample_msgspec(): + # Initialize storage with path where files will be saved + storage = pys.sqlite_storage('storage.db') + + @pys.saveable + class Author(msgspec.Struct): + id: str + name: str + + # Persist model Author + leo = Author(id='leo', name='Leo Tolstoy') + leo_id = storage.save(leo) # Load model Author by its ID and check it's the same another_leo = storage.load(Author, leo_id)