SQLAlchemy的DateTime
类型允许timezone=True
参数将非天真的日期时间对象保存到数据库,并返回它.有没有办法修改tzinfo
SQLAlchemy传入的时区,所以它可能是,例如,UTC?我意识到我可以使用default=datetime.datetime.utcnow
; 然而,这是一个天真的时间,很乐意接受有人在一个天真的基于timezone=True
本地时间的日期时间,即使我使用它,因为它使本地或UTC时间不天真没有基准时区来规范化它.我已经尝试过(使用pytz)使日期时间对象不天真,但是当我将它保存到数据库时,它又回归天真.
注意datetime.datetime.utcnow如何不能timezone=True
很好地工作:
import sqlalchemy as sa from sqlalchemy.sql import select import datetime metadata = sa.MetaData('postgres://user:pass@machine/db') data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(timezone=True), default=datetime.datetime.utcnow) ) metadata.create_all() engine = metadata.bind conn = engine.connect() result = conn.execute(data_table.insert().values(id=1)) s = select([data_table]) result = conn.execute(s) row = result.fetchone()
(1,datetime.datetime(2009,1,6,0,9,36,891887))
row[1].utcoffset()
datetime.timedelta(-1,64800)#这是我的本地时间偏移!!
datetime.datetime.now(tz=pytz.timezone("US/Central"))
datetime.timedelta(-1,64800)
datetime.datetime.now(tz=pytz.timezone("UTC"))
datetime.timedelta(0)#UTC
即使我将其更改为显式使用UTC:
...
data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(timezone=True), default=datetime.datetime.now(tz=pytz.timezone('UTC'))) ) row[1].utcoffset()
...
datetime.timedelta(-1,64800)#它没有使用我明确添加的时区
或者,如果我放弃timezone=True
:
...
data_table = sa.Table('data', metadata, sa.Column('id', sa.types.Integer, primary_key=True), sa.Column('date', sa.types.DateTime(), default=datetime.datetime.now(tz=pytz.timezone('UTC'))) ) row[1].utcoffset() is None
...
真的#这次甚至都没有为数据库保存时区
iny.. 18
http://www.postgresql.org/docs/8.3/interactive/datatype-datetime.html#DATATYPE-TIMEZONES
所有时区感知日期和时间都以UTC格式存储在内部.在显示给客户端之前,它们将在timezone配置参数指定的区域中转换为本地时间.
使用postgresql存储它的唯一方法是单独存储它.
http://www.postgresql.org/docs/8.3/interactive/datatype-datetime.html#DATATYPE-TIMEZONES
所有时区感知日期和时间都以UTC格式存储在内部.在显示给客户端之前,它们将在timezone配置参数指定的区域中转换为本地时间.
使用postgresql存储它的唯一方法是单独存储它.
在这个问题的答案中给出了一个解决方案:
您可以通过以UTC格式存储数据库中的所有(日期)时间对象,并在检索时将生成的天真日期时间对象转换为有意识的对象来避免这种情况.
唯一的缺点是你丢失了时区信息,但无论如何,将你的日期时间对象存储在utc中可能是个好主意.
如果您关心时区信息,我会单独存储它,并且只在最后一个可能的实例中将utc转换为本地时间(例如在显示之前)
或者你可能根本不需要关心,并且可以使用运行程序的机器上的本地时区信息,或者用户的浏览器(如果它是webapp).