Calcola i timestamp all'interno del tuo DB, non del tuo client
Per sanità di mente, probabilmente vorrai aver datetimes
calcolato tutto dal tuo server DB, piuttosto che dal server delle applicazioni. Il calcolo del timestamp nell'applicazione può causare problemi poiché la latenza della rete è variabile, i client riscontrano una deriva dell'orologio leggermente diversa e diversi linguaggi di programmazione occasionalmente calcolano il tempo in modo leggermente diverso.
SQLAlchemy ti permette di farlo passando func.now()
o func.current_timestamp()
(sono alias l'uno dell'altro) che dice al DB di calcolare il timestamp stesso.
Usa SQLALchemy's server_default
Inoltre, per impostazione predefinita in cui si sta già dicendo al DB di calcolare il valore, è generalmente meglio usare server_default
invece di default
. Questo dice a SQLAlchemy di passare il valore predefinito come parte dell'istruzione CREATE TABLE
.
Ad esempio, se si scrive uno script ad hoc su questa tabella, utilizzando server_default
significa che non sarà necessario preoccuparsi di aggiungere manualmente una chiamata timestamp allo script: il database lo imposterà automaticamente.
Comprensione di SQLAlchemy onupdate
/server_onupdate
SQLAlchemy supporta inoltre in onupdate
modo che ogni volta che la riga viene aggiornata inserisca un nuovo timestamp. Ancora una volta, è meglio dire al DB di calcolare il timestamp stesso:
from sqlalchemy.sql import func
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
C'è un server_onupdate
parametro, ma a differenza server_default
, in realtà non imposta nulla sul lato server. Dice solo a SQLalchemy che il tuo database cambierà la colonna quando si verifica un aggiornamento (forse hai creato un trigger sulla colonna ), quindi SQLAlchemy chiederà il valore restituito in modo che possa aggiornare l'oggetto corrispondente.
Un altro potenziale gotcha:
Potresti essere sorpreso di notare che se apporti una serie di modifiche all'interno di una singola transazione, tutte hanno lo stesso timestamp. Questo perché lo standard SQL lo specificaCURRENT_TIMESTAMP
restituisce valori basati sull'inizio della transazione.
PostgreSQL fornisce la non-SQL standard statement_timestamp()
e clock_timestamp()
che fare il cambiamento all'interno di una transazione. Documenti qui: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
Timestamp UTC
Se si desidera utilizzare i timestamp UTC, func.utcnow()
nella documentazione di SQLAlchemy viene fornito uno stub di implementazione . Tuttavia, è necessario fornire autonomamente funzioni appropriate specifiche del driver.