sqlalchemy时间戳对多个列给出不一致的时间

0 投票
1 回答
31 浏览
提问于 2025-04-14 18:33

我在用Flask搭配SQLAlchemy这个工具,下面是我模型的一个简化版本:

class RenterLead(BaseModel):

    __tablename__ = "renter_leads"

    uuid = db.Column(db.String, nullable=False, primary_key=True)

    owner = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)

    name = db.Column(db.String)

    email = db.Column(db.String)

    phone_number = db.Column(db.String)

    inserted_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow,
                            server_default=func.now())

    modified_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow,
                            server_default=func.now())

我发现,当我使用这个模型插入新记录时,inserted_at(插入时间)和modified_at(修改时间)这两个时间戳之间会有几毫秒的差别(这不是我想要的,也不是我预期的)。需要注意的是,当我用这种结构创建表后,如果直接在数据库里插入一条记录,而不通过ORM的话,inserted_atmodified_at的时间戳实际上是完全一样的。这是我想要的效果,我做这个测试是为了验证我观察到的问题是由ORM引起的,而在数据库层面是不存在的。

我想我知道为什么时间戳会不同(因为python的datetime.utcnow函数被调用了两次,每个列一次,所以得到的值会稍微不同)。但我不知道该怎么解决这个问题。我想我可以去掉default,只用server_default。但这样可能会引发其他问题,比如在未提交的模型中数据不存在。那么在SQLAlchemy中处理这个问题的正确方法是什么呢?我想我不是第一个遇到这个问题的人。

1 个回答

0

你可以去掉默认值来解决这个问题。每次调用 datetime.utcnow() 这个函数时,它都会单独计算一次。

    inserted_at = db.Column(db.DateTime, nullable=False,
                            server_default=func.now())

    modified_at = db.Column(db.DateTime, nullable=False,
                            server_default=func.now(), onupdate=func.now())

想了解更多关于 server_default 的信息,可以查看这个 SQLAlchemy 默认日期时间 的链接。

撰写回答