我有一些像这样定义的 SQLAlchemy 模型:
class TimeData(object):
__table_args__ = {"extend_existing": True}
created_on = Column(DateTime(timezone=True), server_default=db.func.now())
updated_on = Column(
DateTime(timezone=True),
server_default=db.func.now(),
server_onupdate=db.func.now(),
onupdate=db.func.now(),
)
class Article(db.Model, TimeData):
id = Column(db.Integar, primary_key=True)
title = Column(db.Text)
contents = Column(db.Text)
last_reviewed_on = Column(db.DateTime)
class Review(db.Model, TimeData):
id = Column(db.Integer, primary_key=True)
review = Column(db.Text)
rating = Column(db.Integer)
read_on = Column(db.DateTime)
可以看到,从
DateTime
类继承的 TimeData
对象都标有 timezone=True
,而模型本身定义的日期则没有。序列化时会产生两种不同类型的日期字符串。
created_on
被序列化为类似 2019-11-25T01:53:05.576Z
的东西,最后带有 Z,而像 read_on
这样的值则被序列化为不带 Z 的 2019-11-25T01:53:05.576
。由于我们将所有内容存储在 UTC 中,因此数据库中的日期信息是美好的。但是当浏览器评估日期时,序列化输出会在客户端引起问题。带 Z 的读取为 UTC,不带 Z 的读取为本地时间。
作为解决方案,迁移模型似乎不起作用。当
timezone=True
添加到模型时,Flask-Migrate (Alembic) 不会检测到模型中的任何更改。
如何将日期迁移到带有时区的日期?
我有一个类似的问题,我最终通过将
timezone=True
添加到我的日期时间字段来解决它。
你是对的,默认情况下,Flask-Migrate 不会拾取该更改,但在将
compare_type=true
添加到 env.py 中的配置后,它会拾取该更改。
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True
)
详情请参阅:Alembic 可以自动生成列更改吗?
生成迁移并升级数据库后,我的日期时间字段在输出中全部返回 UTC(末尾带有 z)。