|
| 1 | +from typing import Optional, List |
| 2 | + |
| 3 | +import pytest |
| 4 | +from sqlalchemy.dialects.postgresql import JSON, JSONB |
| 5 | +from sqlalchemy_nested_mutable._compat import pydantic |
| 6 | +import sqlalchemy as sa |
| 7 | +from sqlalchemy.orm import ( |
| 8 | + DeclarativeBase, |
| 9 | + Mapped, |
| 10 | + mapped_column, |
| 11 | +) |
| 12 | + |
| 13 | +from sqlalchemy_nested_mutable import MutablePydanticBaseModel |
| 14 | + |
| 15 | + |
| 16 | +class Base(DeclarativeBase): |
| 17 | + pass |
| 18 | + |
| 19 | + |
| 20 | +class Addresses(MutablePydanticBaseModel): |
| 21 | + class AddressItem(pydantic.BaseModel): |
| 22 | + street: str |
| 23 | + city: str |
| 24 | + area: Optional[str] |
| 25 | + |
| 26 | + work: List[AddressItem] = [] |
| 27 | + home: List[AddressItem] = [] |
| 28 | + |
| 29 | + |
| 30 | +class User(Base): |
| 31 | + __tablename__ = "user_account" |
| 32 | + |
| 33 | + id: Mapped[int] = mapped_column(primary_key=True) |
| 34 | + name: Mapped[str] = mapped_column(sa.String(30)) |
| 35 | + addresses_default: Mapped[Optional[Addresses]] = mapped_column(Addresses.as_mutable()) |
| 36 | + addresses_json: Mapped[Optional[Addresses]] = mapped_column(Addresses.as_mutable(JSON)) |
| 37 | + addresses_jsonb: Mapped[Optional[Addresses]] = mapped_column(Addresses.as_mutable(JSONB)) |
| 38 | + |
| 39 | + |
| 40 | +@pytest.fixture(scope="module", autouse=True) |
| 41 | +def _with_tables(session): |
| 42 | + Base.metadata.create_all(session.bind) |
| 43 | + yield |
| 44 | + session.execute(sa.text(""" |
| 45 | + DROP TABLE user_account CASCADE; |
| 46 | + """)) |
| 47 | + session.commit() |
| 48 | + |
| 49 | + |
| 50 | +def test_mutable_pydantic_type(session): |
| 51 | + session.add(User(name="foo")) |
| 52 | + session.commit() |
| 53 | + assert session.scalar(sa.select(sa.func.pg_typeof(User.addresses_default))) == "jsonb" |
| 54 | + assert session.scalar(sa.select(sa.func.pg_typeof(User.addresses_json))) == "json" |
| 55 | + assert session.scalar(sa.select(sa.func.pg_typeof(User.addresses_jsonb))) == "jsonb" |
0 commit comments