SQLAlchemy Nested Mutable Types.
Project description
SQLAlchemy-Nested-Mutable
An advanced SQLAlchemy column type factory that helps map compound Python types (e.g. list, dict, Pydantic Model and their hybrids) to database types (e.g. ARRAY, JSONB),
And keep track of mutations in deeply nested data structures so that SQLAlchemy can emit proper UPDATE statements.
SQLAlchemy-Nested-Mutable is highly inspired by SQLAlchemy-JSON[0][1].
However, it does not limit the mapped Python type to be dict or list.
Why this package?
-
By default, SQLAlchemy does not track in-place mutations for non-scalar data types such as
listanddict(which are usually mapped withARRAYandJSON/JSONB). -
Even though SQLAlchemy provides an extension to track mutations on compound objects, it's too shallow, i.e. it only tracks mutations on the first level of the compound object.
-
There exists the SQLAlchemy-JSON package to help track mutations on nested
dictorlistdata structures. However, the db type is limited toJSON(B). -
Also, I would like the mapped Python types can be subclasses of the Pydantic BaseModelModel, which have strong schemas, with the db type be schema-less JSON.
Installation
pip install sqlalchemy-nested-mutable
Usage
NOTE the example below is first updated in
examples/user-addresses.pyand then updated here.
from typing import Optional, List
import pydantic
import sqlalchemy as sa
from sqlalchemy.orm import Session, DeclarativeBase, Mapped, mapped_column
from sqlalchemy_nested_mutable import MutablePydanticBaseModel
class Base(DeclarativeBase):
pass
class Addresses(MutablePydanticBaseModel):
"""A container for storing various addresses of users.
NOTE: for working with pydantic model, use a subclass of `MutablePydanticBaseModel` for column mapping.
However, the nested models (e.g. `AddressItem` below) should be direct subclasses of `pydantic.BaseModel`.
"""
class AddressItem(pydantic.BaseModel):
street: str
city: str
area: Optional[str]
preferred: AddressItem
work: Optional[AddressItem]
home: Optional[AddressItem]
others: List[AddressItem] = []
class User(Base):
__tablename__ = "user_account"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(sa.String(30))
addresses: Mapped[Addresses] = mapped_column(Addresses.as_mutable(), nullable=True)
engine = sa.create_engine("sqlite://")
Base.metadata.create_all(engine)
with Session(engine) as s:
s.add(u := User(name="foo", addresses={"preferred": {"street": "bar", "city": "baz"}}))
assert isinstance(u.addresses, MutablePydanticBaseModel)
s.commit()
u.addresses.preferred.street = "bar2"
s.commit()
assert u.addresses.preferred.street == "bar2"
u.addresses.others.append(Addresses.AddressItem.parse_obj({"street": "bar3", "city": "baz3"}))
s.commit()
assert isinstance(u.addresses.others[0], Addresses.AddressItem)
print(u.addresses.dict())
For more usage, please refer to the following test files:
- tests/test_mutable_list.py
- tests/test_mutable_dict.py
- tests/test_mutable_pydantic_type.py
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqlalchemy_nested_mutable-0.2.0.tar.gz.
File metadata
- Download URL: sqlalchemy_nested_mutable-0.2.0.tar.gz
- Upload date:
- Size: 7.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/4.0.2 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23fd737571eed48c045ff099bd87cbd440e295f1596be8e875cf4873b3f995ee
|
|
| MD5 |
a37f8c266c84cbfacea27335b5d2ce7a
|
|
| BLAKE2b-256 |
2086da3f80bdc2549be2eff963a57e6cffdad777fb9ba9b3a7aa93e4930e8ba2
|
File details
Details for the file sqlalchemy_nested_mutable-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sqlalchemy_nested_mutable-0.2.0-py3-none-any.whl
- Upload date:
- Size: 8.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/4.0.2 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c804585426f3c511c2c5cdae31ad9bce48dd3cd6735950b2f42c81f40df824c4
|
|
| MD5 |
d65e5703f951ac36741d30f6dea473ff
|
|
| BLAKE2b-256 |
8f1d6e5bce9ded54aea330cfbc3ae1d6964077e2ff54ab76904f644cc821ebd2
|