Тип SQLAlchemy DateTime
позволяет аргументу timezone=True
сохранять в базе данных объект, не являющийся наивным datetime, и возвращать его как таковой. Есть ли способ изменить часовой пояс tzinfo
, который передает SQLAlchemy, так что это может быть, например, UTC? Я понимаю, что могу просто использовать default=datetime.datetime.utcnow
; тем не менее, это наивное время, которое с радостью согласится с тем, что кто-то перешел в наивную локальную дату и время, даже если я использовал timezone=True
с ним, потому что это делает время локального или UTC не наивным без базового часового пояса, чтобы нормализовать его с помощью, Я попытался (используя pytz), чтобы сделать объект datetime не наивным, но когда я сохраняю его в БД, он возвращается наивным.
Обратите внимание, как datetime.datetime.utcnow не работает с timezone=True
так хорошо:
import sqlalchemy as sa
from sqlalchemy.sql import select
import datetime
metadata = sa.MetaData('postgres://user:[email protected]/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 на этот раз