Postgres + SQLAlchemy使用default = func.now()时将时间转换为UTC

ora*_*nge 7 python postgresql timezone datetime sqlalchemy

我有一个定义的SQLAlchemy表

foo_table = Table('foo', metadata,
    Column('id', Integer, primary_key=True),
    Column('created_on', DateTime, default=func.now()),
    ...
)
Run Code Online (Sandbox Code Playgroud)

这在Postgres中创建了一个表

CREATE TABLE foo
(
  id serial NOT NULL,
  created_on timestamp without time zone,
  ...
)
Run Code Online (Sandbox Code Playgroud)

正确设置本地时区(检查Python datetime.datetime.now()显示我的本地时间),但每当我在foo_table没有明确设置的情况下插入行时created_on,使用的时间是当前UTC而不是我当地时间(例如"2015-07-29 16:38: 08.112192" ).

当我尝试created_on手动设置时,这一切都运行良好,但似乎Postgres或SQLAlchemy正在将时间转换为UTC,func.now()以便分配时间戳.

如何让SQLAlchemy或Postgres只用我当前的当地时间创建一个记录?

小智 6

这里的关键部分是将 created_on 列定义为“没有时区的时间戳”。

从这里的文档:

http://www.postgresql.org/docs/current/static/datatype-datetime.html

在已确定为没有时区的时间戳的文字中,PostgreSQL 将默默地忽略任何时区指示。也就是说,结果值源自输入值中的日期/时间字段,不会针对时区进行调整。

对于带时区的时间戳,内部存储的值始终采用 UTC(世界协调时间,传统上称为格林威治标准时间,GMT)。使用该时区的适当偏移量将具有指定显式时区的输入值转换为 UTC。如果输入字符串中未指定时区,则假定它位于系统的 TimeZone 参数指示的时区中,并使用时区区域的偏移量转换为 UTC。

因此,实际上,您丢弃了时区信息,只剩下存储的 UTC 日期。

在 SQLAlchemy 的情况下,要创建带有“timestamp with time zone”的列,您需要添加一些效果:

日期时间(时区=真)

根据此处的文档:

http://docs.sqlalchemy.org/en/rel_0_9/core/type_basics.html

这应该让您保存所需的时区信息,并检索它。

希望这有助于回答您的问题并让您继续前进。祝你好运。=)

  • 我不想存储时区信息。系统应该与时区无关,并且“func.now()”的行为应该与初始化“created_on=datetime.datetime.now()”相同。 (2认同)