Python 博士后&x2B;SQLAlchemy使用default=func.now()时将时间转换为UTC

Python 博士后&x2B;SQLAlchemy使用default=func.now()时将时间转换为UTC,python,postgresql,datetime,sqlalchemy,timezone,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 wit

我有一个定义了的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_表中插入一行时,如果没有明确设置
created_on
,则使用的时间是当前UTC而不是我的本地时间(例如“2015-07-29 16:38:08.112192”)

当我尝试手动设置
created\u on
时,这一切都可以正常工作,但似乎Postgres或SQLAlchemy正在将时间转换为UTC,而将时间留给
func.now()
来分配时间戳


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

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

从这里的文档:

在已确定为不带时区的时间戳的文本中,PostgreSQL将自动忽略任何时区指示。也就是说,结果值是从输入值中的日期/时间字段派生的,并且不针对时区进行调整

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

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

对于SQLAlchemy,要创建带有“timestamp with time zone”的列,您需要添加以下内容:

日期时间(时区=真)

根据此处的文档:

它可以让您保存所需的时区信息,并检索它


希望这有助于回答你的问题,让你走上正轨。祝你好运

我不想存储时区信息。系统应该是时区不可知的,
func.now()
的行为应该与初始化
created_on=datetime.datetime.now()
的行为相同。我认为
在时区中没有时区的时间戳可能更合适,这似乎尊重当地时间:甚至更好,设置目标时区时间戳转换为,如下所述:。这不需要任何代码更改。与此无关,但对将来的读者来说:您希望
default=func.现在
不带
()
,否则默认值将是导入文件的时间(例如,如果是webapp,则是启动服务器的时间),而不是插入行的当前时间。。。或者
server\u default=text('now()')
@ThiefMaster如果您的评论是错误的,用户应该使用
default=func.now()
,如文档中所述:
func.now()返回SQL表达式对象,该对象将把“now”函数呈现到正在发出的SQL中
我希望
func.now
不起作用。