admin管理员组文章数量:1191737
I have the following model definitions in SQLModel:
class UserBase(SQLModel):
first_name: str = Field(min_length=2, max_length=50)
last_name: str = Field(min_length=2, max_length=50)
email: EmailStr
class User(UserBase, table=True):
id: int | None = Field(default=None, primary_key=True)
created_at: datetime = Field(default_factory=get_current_utc_time)
updated_at: datetime = Field(default_factory=get_current_utc_time)
last_login_at: datetime | None = None
email: EmailStr = Field(unique=True)
where get_current_utc_time
is a function that simply returns datetime.now(UTC)
. I would like created_at
and updated_at
to be exactly the same when a user is first created in the database. This currently doesn't happen because get_current_utc_time
is called twice.
I tried the following alteration:
updated_at: datetime = created_at
Bizarrely, the value of updated_at
is still different from created_at
.
Could anyone help with the following questions:
- Why is the value of
updated_at
still different fromcreated_at
? - Is it possible to achieve the desired behaviour "out of the box" with SQLModel?
- Could I write a custom validator to achieve this, and if so how would I ensure that it is called by SQLModel, even though
table=True
? (given this behaviour: )
I have the following model definitions in SQLModel:
class UserBase(SQLModel):
first_name: str = Field(min_length=2, max_length=50)
last_name: str = Field(min_length=2, max_length=50)
email: EmailStr
class User(UserBase, table=True):
id: int | None = Field(default=None, primary_key=True)
created_at: datetime = Field(default_factory=get_current_utc_time)
updated_at: datetime = Field(default_factory=get_current_utc_time)
last_login_at: datetime | None = None
email: EmailStr = Field(unique=True)
where get_current_utc_time
is a function that simply returns datetime.now(UTC)
. I would like created_at
and updated_at
to be exactly the same when a user is first created in the database. This currently doesn't happen because get_current_utc_time
is called twice.
I tried the following alteration:
updated_at: datetime = created_at
Bizarrely, the value of updated_at
is still different from created_at
.
Could anyone help with the following questions:
- Why is the value of
updated_at
still different fromcreated_at
? - Is it possible to achieve the desired behaviour "out of the box" with SQLModel?
- Could I write a custom validator to achieve this, and if so how would I ensure that it is called by SQLModel, even though
table=True
? (given this behaviour: https://github.com/fastapi/sqlmodel/issues/52)
- Which RDBMS are you targetting? – snakecharmerb Commented Jan 24 at 8:15
- @snakecharmerb I'm using PostgreSQL - but does that make any difference to the SQLModel init behaviour? – sophocles99 Commented 13 hours ago
1 Answer
Reset to default 0When you did update_at: datetime = created_at
it did not work, because python judges created_at
at class definition time not instance creation time. They were different because basically default values are evaluated independently at instance creation time.
Solution to this could be during model creation setting updated_at
to None and then during initializing setting it as created_at
...
class User(UserBase, table=True):
id: int | None = Field(default=None, primary_key=True)
created_at: datetime = Field(default_factory=get_current_utc_time)
updated_at: datetime | None = None
last_login_at: datetime | None = None
email: EmailStr = Field(unique=True)
def __init__(self, **data):
super().__init__(**data)
if self.updated_at is None:
self.updated_at = self.created_at
The solution will solve the problem but the more maintainable solution could be create a paired factory function, something like...
inital_time_factory, shared_time_factory = create_timestamp_pair()
class User(UserBase, table=True):
id: int | None = Field(default=None, primary_key=True)
created_at: datetime = Field(default_factory=initial_time_factory)
updated_at: datetime = Field(default_factory=shared_time_factory)
last_login_at: datetime | None = None
email: EmailStr = Field(unique=True)
the create_timestamp_pair()
creates a pair of factory functions that returns the same timestamp.
Finally, I dont think validators to be the best solution, because iguess they are executed after the fields are set, not sure about this, you will have to manage validation order properly.
本文标签: How can I create two fields in a SQLModel model with identical default datetimesStack Overflow
版权声明:本文标题:How can I create two fields in a SQLModel model with identical default datetimes? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738454388a2087673.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论