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

时间:2015-07-30 04:16:43

标签: python postgresql datetime sqlalchemy timezone

我有一个定义的SQLAlchemy表

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

在Postgres中创建一个表

CREATE TABLE foo
(
  id serial NOT NULL,
  created_on timestamp without time zone,
  ...
)

正确设置本地时区(检查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只使用当前的当地时间创建记录?

1 个答案:

答案 0 :(得分:4)

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

从这里的文档:

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

  

在一个已被确定为没有时区的时间戳的文字中,PostgreSQL将默默地忽略任何时区指示。也就是说,结果值是从输入值中的日期/时间字段派生的,不会根据时区进行调整。

     

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

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

对于SQLAlchemy,要创建具有“带时区的时间戳”的列,您需要添加一些效果:

  

日期时间(时区= TRUE)

根据此处的文件:

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

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

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