我遇到一个问题,SQLAlchemy(版本0.6.4和0.6.8)在提交到SQLite数据库时丢失了来自datetime
对象的时区信息,其中列由SQLAlchemy {{1}定义} .class。 (我意识到SQLAlchemy正在将其转换为字符串并返回,这是我认为是问题的一半)。
由于代码比单词更响亮,我有以下示例/再现器:
DateTime
从控制台输出,主要是它将记录作为值import datetime, pytz, sqlalchemy
from sqlalchemy import create_engine, Column, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()
class Example(Base):
__tablename__ = "example"
id = Column(Integer, primary_key=True)
date = Column(DateTime(timezone=True))
def __init__(self, date):
self.date = date
Base.metadata.create_all(engine)
aucklandtz = pytz.timezone('Pacific/Auckland')
exdatetime = datetime.datetime(2011,8,8,2,23)
print aucklandtz, exdatetime
# inject TZ to exdatetime:
injdatetime = aucklandtz.localize(exdatetime)
print injdatetime
newrecord = Example(injdatetime)
print newrecord.date
session.add(newrecord)
session.commit()
print newrecord.date
插入SQLite。
是否有一种简单的方法可以解决这个问题,或者我是否需要将TZ信息添加到单独的列/将所有内容存储为时间戳并在格式之间进行操作?
答案 0 :(得分:6)
Python的strptime
方法不支持%z
格式化指令,因此无法从数据库中的字符串中取出时区。我认为这就是它没有存储的原因。
您有两种选择。您已经提到过 - 将时区存储在另一列中。
然而,通常建议的解决此问题的方法是不同的。无论是在Python中还是在数据库中使用datetime
存储时区,都要立即将所有datetime
转换为UTC
从用户接收它们,并且只处理{UTC
1}}内部。之后,当您必须将结果显示给用户时,请将其转换为适当的时区。
这将实际时间与您不能依赖的实际时间分开。如果您的计划用户从奥克兰搬到日本,或新西兰政府改变他们的时区怎么办?
答案 1 :(得分:1)
Armin Ronacher发表了一篇名为““Eppur si muove!”* – Dealing with Timezones in Python”的优秀博客文章。它主要说如下: