如何解决使 SQLAlchemy 使用本地时区作为数据库生成的日期
在我的 sqlAlchemy 模型中,数据库 (sqlite) 在写操作期间更新时间戳列:
class DBObject(declarative_base()):
__tablename__ = 'dbobj'
id = Column(Integer,primary_key=True,autoincrement=True)
date = Column(DateTime(timezone=True))
text = Column(String(64))
created_at = Column(DateTime(timezone=True),server_default=func.Now())
updated_at = Column(DateTime(timezone=True),server_default=func.Now(),onupdate=func.Now())
engine = create_engine('sqlite:///:memory:')
DBObject.Metadata.create_all(bind=engine)
然而,这似乎并没有考虑到时区。如何让 sqlAlchemy 将这些时间戳转换为我的本地时区? (我知道 sqlite 仅适用于 UTC)
fmt = '%Y-%m-%d %H:%M:%s'
print(f"tzone = {time.timezone}s") # Local timezone offset to UTC.
print(f"Now = {datetime.Now().strftime(fmt)}") # Current local time.
s = Session(bind=engine)
try:
# Create new entry.
s.add(DBObject(date=datetime.Now(),text='created'))
s.flush()
# Wait a bit
time.sleep(1)
# Update entry.
obj = s.query(DBObject).one()
obj.text = 'updated'
s.flush()
# Read entry and print dates.
obj = s.query(DBObject).one()
print(f"date = {obj.date.strftime(fmt)}")
print(f"create = {obj.created_at.strftime(fmt)}")
print(f"update = {obj.updated_at.strftime(fmt)}")
finally:
s.close()
实际输出:
tzone = -3600s
Now = 2021-01-26 18:40:15
date = 2021-01-26 18:40:15
create = 2021-01-26 17:40:15
update = 2021-01-26 17:40:16
预期输出:
tzone = -3600s
Now = 2021-01-26 18:40:15
date = 2021-01-26 18:40:15
create = 2021-01-26 18:40:15
update = 2021-01-26 18:40:16
我还尝试了什么:
- 删除
timezone=True
中的DateTime
- 使用
sqlalchemy.TIMESTAMP
(有或没有timezone=True
) - 使用
default
而不是server_default
- 使用
datetime.utcNow
而不是func.Now()
请注意,这包括对非常相似的 stackoverflow 问题(例如 SQLAlchemy default DateTime)的解决方案。 这些似乎都没有任何区别。 sqlAlchemy 和 sqlite 函数似乎都只能在 UTC 中工作。我发现的唯一解决方案是完全删除他们的日期时间功能:
class DBObject(declarative_base()):
__tablename__ = 'dbobj'
id = Column(Integer,autoincrement=True)
date = Column(DateTime)
text = Column(String(64))
created_at = Column(DateTime,default=datetime.Now)
updated_at = Column(DateTime,default=datetime.Now,onupdate=datetime.Now)
在这种情况下,我得到了预期的输出,但我猜所有数据库本机时间函数仍将关闭,因此无法在任何 sql 查询中使用。
如何告诉 sqlAlchemy 和/或 sqlite 在本地时区返回日期时间对象? 有什么办法可以使用这两者并让数据库分配日期无需一直转换为 UTC 或从 UTC 转换?我好像遗漏了什么。
奖金要求:
使用 s.query(DBObject).all()
读取需要返回与使用熊猫读取相同的日期:pd.read_sql(s.query(DBObject).statement,s.bind)
版本:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。