SQLAlchemy のDateTime
型では、timezone=True
引数を使用して、naive でない datetime オブジェクトをデータベースに保存し、そのまま返すことができます。SQLAlchemy が渡すタイムゾーンを変更してtzinfo
、たとえば UTC にする方法はありますか? を使用できることに気づきましたdefault=datetime.datetime.utcnow
。ただし、これは単純な localtime ベースの datetime を渡す人を喜んで受け入れる単純な時間です。これを使用timezone=True
したとしても、正規化するベース タイムゾーンがなくてもローカル時間または UTC 時間が非単純になるためです。( pytzを使用して) datetime オブジェクトを非ナイーブにしようとしましたが、これを DB に保存すると、ナイーブとして返されます。
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, 日時.日時(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
...
True # 今回はタイムゾーンをデータベースに保存しませんでした