SQLAlchemy DateTimeタイムゾーン
-
03-07-2019 - |
質問
SQLAlchemyの DateTime
型では、 timezone = True
引数を使用して、非単純なdatetimeオブジェクトをデータベースに保存し、そのまま返すことができます。 SQLAlchemyが渡す tzinfo
のタイムゾーンを、UTCなどに変更する方法はありますか? default = datetime.datetime.utcnow
だけを使用できることに気付きました。ただし、これは、 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、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
...
True#今回はdbにタイムゾーンさえ保存しませんでした
解決
http://www.postgresql.org/ docs / 8.3 / interactive / datatype-datetime.html#DATATYPE-TIMEZONES
すべてのタイムゾーン対応の日付と時刻は内部的にUTCで保存されます。これらは、クライアントに表示される前に、timezone構成パラメーターで指定されたゾーンの現地時間に変換されます。
postgresqlで保存する唯一の方法は、個別に保存することです。
他のヒント
解決策はこの質問’ s で提供されています回答:
UTCでデータベースにすべての(日付)時間オブジェクトを保存し、結果のnaï veのdatetimeオブジェクトを取得時に認識オブジェクトに変換することで、これを回避できます。
唯一の欠点はタイムゾーン情報を失うことですが、とにかくutcにdatetimeオブジェクトを保存することをお勧めします。
タイムゾーン情報が必要な場合は、それを個別に保存し、utcを最後の可能なインスタンスの現地時間にのみ変換します(表示する直前など)
または多分気にする必要はないかもしれませんし、あなたがプログラムを実行しているマシンや、webappであればユーザーのブラウザからローカルタイムゾーン情報を使うことができます8217; p>