Skip to content

Commit

Permalink
feat: add data initialization on model load
Browse files Browse the repository at this point in the history
- Introduced `init_on_load` to handle JSON deserialization for fields using Pydantic models.
- Enhanced tests to verify the deserialization of complex fields in `ExampleWithId`.

Generated-by: aiautocommit
  • Loading branch information
iloveitaly committed Jan 11, 2025
1 parent 1213f2f commit 00a90ce
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion test/serialization_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import get_args, get_origin

from pydantic import BaseModel as PydanticBaseModel

from activemodel import BaseModel
from activemodel.mixins import TypeIDMixin
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import reconstructor
from sqlmodel import Field

TYPEID_PREFIX = "myid"
Expand All @@ -18,6 +21,30 @@ class ExampleWithId(BaseModel, TypeIDMixin(TYPEID_PREFIX), table=True):
object_field: SubObject = Field(sa_type=JSONB())
unstructured_field: dict = Field(sa_type=JSONB())

@reconstructor
def init_on_load(self):
for field_name, field_info in self.model_fields.items():
raw_value = getattr(self, field_name, None)

if raw_value is None:
continue

annotation = field_info.annotation
origin = get_origin(annotation)
args = get_args(annotation)

# e.g. list[SomePydanticModel]
if origin is list and len(args) == 1:
model_cls = args[0] # e.g. SomePydanticModel
if issubclass(model_cls, PydanticBaseModel) and isinstance(
raw_value, list
):
parsed_value = [model_cls(**item) for item in raw_value]
setattr(self, field_name, parsed_value)
# single model
elif issubclass(annotation, PydanticBaseModel):
setattr(self, field_name, annotation(**raw_value))


def test_json_serialization(create_and_wipe_database):
sub_object = SubObject(name="test", value=1)
Expand All @@ -29,4 +56,7 @@ def test_json_serialization(create_and_wipe_database):

fresh_example = ExampleWithId.get(example.id)

breakpoint()
assert fresh_example is not None
assert isinstance(fresh_example.object_field, SubObject)
assert isinstance(fresh_example.list_field[0], SubObject)
assert isinstance(fresh_example.unstructured_field, dict)

0 comments on commit 00a90ce

Please sign in to comment.