我正在尝试为python/sqlalchemy脚本添加时区支持。我研究过时区并使用过pytz。我知道我应该尽可能多地使用UTC,并且只显示当地时间。由于应用程序的性质,这非常容易。
一切都正常,只是当我插入UTC数据时,在进入数据库之前,它会以某种方式转换为当地时间(BST),我完全不知道为什么会发生这种情况,以及如何避免这种情况。
我的表格(postgres)定义如下(仅相关部分):
fpp=> d foo;
Table "public.foo"
Column | Type | Modifiers
-----------+-----------------------------+-------------------------------------------------------------
x | integer |
y | integer |
when_utc | timestamp without time zone |
当sqlalchemy进行插入时,我已经调试了它。这就是发生的事情:
2016-07-28 17:16:27,896 INFO sqlalchemy.engine.base.Engine INSERT INTO
foo (x, y, "when_utc") VALUES (%(x)s, %(y)s, %(when_utc)s) RETURNING fb_foo.id
2016-07-28 17:16:27,896 INFO sqlalchemy.engine.base.Engine {
'when_utc': datetime.datetime(2016, 7, 11, 23, 0, tzinfo=<UTC>), 'y': 0, 'x': 0}
因此它插入UTC 2016年11月7日23:00:00。当我在命令行psql中查询它时,我会发现:
fpp=> select x,y,when_utc from foo;
x | y | when_utc
---+---+---------------------
0 | 0 | 2016-07-12 00:00:00
(1 row)
发生了什么事?我坚信没有什么能改变介于两者之间的领域。它似乎只是将夏令时添加到我的数据库条目中。为什么?我该如何避免这种情况?
R
问题是列类型是timestamp without time zone
,而应该是timestamp with time zone
。这可以在SqlAlchemy中使用DateTime(timezone=True)
在声明列时实现。不幸的是,默认值为False。。。有关详细信息,请参阅文档https://docs.sqlalchemy.org/en/13/core/type_basics.html#sqlalchemy.types.DateTime
我也在努力解决这个问题。如果您使用sqlalchemy核心,我发现前面的答案非常有用。但是,这不是我的情况,因为我正在使用sqlalchemy orm。如果你正在使用orm,你可能会对我如何解决它感兴趣。
我是这样映射列的:
import datetime
from sqlalchemy import DateTime
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
class Event(Base):
__tablename__ = "event"
occurred_on: Mapped[datetime.datetime] = mapped_column(DateTime(timezone=True))