计算数据库中的时间戳,而不是客户机
为了保持理智,您可能希望所有的datetimes都由数据库服务器计算,而不是由应用程序服务器计算。在应用程序中计算时间戳可能会导致问题,因为网络延迟是可变的,客户机的时钟漂移略有不同,不同的编程语言偶尔计算时间略有不同。
SQLAlchemy允许您通过传递^{}或^{}(它们是彼此的别名)来实现这一点,后者告诉DB计算时间戳本身。
使用SQLALchemy的server_default
另外,对于已经告诉DB计算值的默认情况,通常最好使用^{},而不是default。这告诉SQLAlchemy将默认值作为CREATE TABLE语句的一部分传递。
例如,如果您针对这个表编写一个特别脚本,使用server_default意味着您不必担心手动向脚本添加时间戳调用——数据库将自动设置它。
了解SQLAlchemy的onupdate/server_onupdate
SQLAlchemy还支持onupdate,以便在更新行时插入新的时间戳。同样,最好告诉数据库自己计算时间戳:from sqlalchemy.sql import func
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
有一个^{}参数,但与server_default不同,它实际上没有设置任何服务器端。它只告诉SQLalchemy当发生更新时,数据库将更改列(也许您创建了一个trigger on the column),因此SQLalchemy将要求返回值,以便它可以更新相应的对象。
另一个潜在的问题是:
您可能会惊讶地注意到,如果您在单个事务中进行一系列更改,它们都具有相同的时间戳。这是因为SQL标准指定CURRENT_TIMESTAMP返回基于事务开始的值。
UTC时间戳
如果要使用UTC时间戳,则SQLAlchemy documentation中提供了func.utcnow()的实现存根。不过,您需要自己提供适当的特定于驱动程序的功能。