SQLAlchemy DateTime
Typ ermöglicht für ein timezone=True
Argument ein nicht naives Datetime-Objekt in der Datenbank zu speichern und es als solches zurückzugeben. Gibt es eine Möglichkeit, die Zeitzone des tzinfo
, die SQLAlchemy übergibt, zu ändern, so könnte es beispielsweise UTC sein? Mir ist klar, dass ich einfach default=datetime.datetime.utcnow
verwenden könnte; Dies ist jedoch eine naive Zeit, die gerne jemanden akzeptieren würde, der ein naives lokales zeitbasiertes Datetime passiert, selbst wenn ich timezone=True
damit verwende, weil es lokale oder UTC-Zeit nicht-naiv macht, ohne eine Basiszeitzone zu haben, um es zu normalisieren. Ich habe versucht (mit pytz), um das Datetime-Objekt nicht naiv zu machen, aber wenn ich dies in der DB speichern, kommt es als naiv zurück.SQLAlchemy DateTime Zeitzone
Hinweis, wie datetime.datetime.utcnow nicht mit timezone=True
funktioniert so gut:
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) #, dass meine Lokalzeit versetzt ist !!
datetime.datetime.now(tz=pytz.timezone("US/Central"))
datetime.timedelta (-1, 64800)
datetime.datetime.now(tz=pytz.timezone("UTC"))
datetime.timedelta (0) #UTC
Auch wenn ich es ändern um explizit UTC zu verwenden:
...
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) # es nicht die Zeitzone verwenden, habe ich hinzugefügt ausdrücklich
Oder wenn ich fallen die 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
...
Wahre # es nicht einmal eine Zeitzone an die DB diesmal
ist der "timezone configuration parameter" die timezone info in der datetime_with_timzone in der gespeicherten Datenbank? –
@Ciastopiekarz Nein. Der Konfigurationsparameter 'timezone' ist ein Client-Verbindungsparameter. Die "Datetime mit Zeitzone", deren Wert in UTC gespeichert wird, wird in die Zeitzone konvertiert, die in diesem Zeitzonenparameter angegeben ist, bevor sie angezeigt oder zurückgegeben wird. Verwenden Sie 'SHOW timezone' um zu prüfen, welchen Wert es für Ihre aktuelle Verbindung hat. Denken Sie darüber nach, was Sie wirklich benötigen: Müssen Sie die Zeit speichern, zu der ein Ereignis aufgetreten ist, oder müssen Sie auch Informationen speichern, in welcher Zeitzone der gespeicherte datetime-Wert tatsächlich entstanden ist? Wenn es Letzteres ist, müssen Sie diese Informationen getrennt speichern. – compostus
wenn ich nur die Zeit kenne, als es auftrat, aber in UTC, das ist wahrscheinlich aktuelle Verbindung, dann werde ich ohne Zeitzoneninfo nie wissen, wann genau die richtige Zeit des Benutzers irgendein Ereignis stattgefunden hat. –