Skip to content

Commit 594aac3

Browse files
committed
For sake of demonstration, add created_at and updated_at fields to CreatedUpdatedMixin used in test
1 parent a88ee75 commit 594aac3

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

tests/test_relationship_inheritance.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
import datetime
12
from typing import Optional
23

4+
from sqlalchemy import DateTime, func
35
from sqlalchemy.orm import declared_attr, relationship
46
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
57

68

79
def test_relationship_inheritance() -> None:
10+
def now():
11+
return datetime.datetime.now(tz=datetime.timezone.utc)
12+
813
class User(SQLModel, table=True):
914
id: Optional[int] = Field(default=None, primary_key=True)
1015
name: str
1116

1217
class CreatedUpdatedMixin(SQLModel):
18+
# Fields in reusable base models must be defined using `sa_type` and `sa_column_kwargs` instead of `sa_column`
19+
# https://github.com/tiangolo/sqlmodel/discussions/743
20+
#
21+
# created_at: datetime.datetime = Field(default_factory=now, sa_column=DateTime(default=now))
22+
created_at: datetime.datetime = Field(
23+
default_factory=now, sa_type=DateTime, sa_column_kwargs={"default": now}
24+
)
25+
1326
# With Pydantic V2, it is also possible to define `created_by` like this:
1427
#
1528
# ```python
@@ -34,6 +47,9 @@ class CreatedUpdatedMixin(SQLModel):
3447
)
3548
)
3649

50+
updated_at: datetime.datetime = Field(
51+
default_factory=now, sa_type=DateTime, sa_column_kwargs={"default": now}
52+
)
3753
updated_by_id: Optional[int] = Field(default=None, foreign_key="user.id")
3854
updated_by: Optional[User] = Relationship(
3955
sa_relationship=declared_attr(
@@ -43,20 +59,34 @@ class CreatedUpdatedMixin(SQLModel):
4359

4460
class Asset(CreatedUpdatedMixin, table=True):
4561
id: Optional[int] = Field(default=None, primary_key=True)
62+
name: str
63+
64+
# Demonstrate that the mixin can be applied to more than 1 model
65+
class Document(CreatedUpdatedMixin, table=True):
66+
id: Optional[int] = Field(default=None, primary_key=True)
67+
name: str
4668

4769
engine = create_engine("sqlite://")
4870

4971
SQLModel.metadata.create_all(engine)
5072

5173
john = User(name="John")
5274
jane = User(name="Jane")
53-
asset = Asset(created_by=john, updated_by=jane)
75+
asset = Asset(name="Test", created_by=john, updated_by=jane)
76+
doc = Document(name="Resume", created_by=jane, updated_by=john)
5477

5578
with Session(engine) as session:
5679
session.add(asset)
80+
session.add(doc)
5781
session.commit()
5882

5983
with Session(engine) as session:
84+
assert session.scalar(select(func.count()).select_from(User)) == 2
85+
6086
asset = session.exec(select(Asset)).one()
6187
assert asset.created_by.name == "John"
6288
assert asset.updated_by.name == "Jane"
89+
90+
doc = session.exec(select(Document)).one()
91+
assert doc.created_by.name == "Jane"
92+
assert doc.updated_by.name == "John"

0 commit comments

Comments
 (0)