El tipo DateTime
de SQLAlchemy permite un argumento timezone=True
para guardar un objeto datetime no ingenuo en la base de datos y devolverlo como tal. ¿Hay alguna manera de modificar la zona horaria del tzinfo
que SQLAlchemy transfiere, por lo que podría ser, por ejemplo, UTC? Me doy cuenta de que podría usar default=datetime.datetime.utcnow
; sin embargo, este es un tiempo ingenuo que aceptaría felizmente a alguien que pasa en un tiempo de calendario basado en tiempo local ingenuo, incluso si usé timezone=True
con él, porque hace que la hora local o UTC no sea ingenua sin tener una zona horaria base para normalizarla. He intentado (usando pytz) hacer que el objeto datetime no sea ingenuo, pero cuando lo guardo en el DB vuelve a ser ingenuo.SQLAlchemy DateTime timezone
Nota cómo datetime.datetime.utcnow no funciona tan bien con 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, 891,887))
row[1].utcoffset()
datetime.timedelta (-1, 64800) # que está compensado mi hora local !!
datetime.datetime.now(tz=pytz.timezone("US/Central"))
datetime.timedelta (-1, 64800)
datetime.datetime.now(tz=pytz.timezone("UTC"))
datetime.timedelta (0) #utc
Incluso si lo cambio para usar explícitamente 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) # que no hizo uso de la zona horaria que añade explícitamente
O si se me cae la 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
...
verdadera # ni siquiera guardar una zona horaria a la db este tiempo
es el "parámetro de configuración de la zona horaria" la información de la zona horaria en el datetime_with_timzone en la base de datos almacenada? –
@Ciastopiekarz No. El parámetro de configuración 'timezone' es un parámetro de conexión del cliente. El 'datetime with time zone', cuyo valor se almacena en UTC, se convierte a la zona horaria especificada en este parámetro' timezone' antes de mostrarlo o devolverlo. Use 'SHOW timezone' para verificar qué valor tiene para su conexión actual. Piense en lo que realmente necesita: ¿necesita almacenar la hora cuando ocurrió un evento, o también necesita almacenar información en qué zona horaria se originó realmente el valor de fecha y hora almacenado? Si es el último, debe almacenar esta información por separado. – compostus
si solo sé la hora en que ocurrió, pero en UTC, esa es probablemente la conexión actual, y luego, sin la información de la zona horaria, nunca sabré cuándo exactamente ocurrió la hora exacta del usuario. –