Calcule las marcas de tiempo dentro de su base de datos, no su cliente
Para la cordura, es probable que desee tener todo datetimes
calculado por su servidor de base de datos, en lugar de por el servidor de aplicaciones. Calcular la marca de tiempo en la aplicación puede ocasionar problemas porque la latencia de la red es variable, los clientes experimentan una deriva del reloj ligeramente diferente, y diferentes lenguajes de programación ocasionalmente calculan el tiempo de manera ligeramente diferente.
SQLAlchemy le permite hacer esto pasando func.now()
o func.current_timestamp()
(son alias entre sí) que le dice a la base de datos que calcule la marca de tiempo.
Use SQLALchemy's server_default
Además, para un valor predeterminado en el que ya le está diciendo a la base de datos que calcule el valor, generalmente es mejor usarlo en server_default
lugar de hacerlo default
. Esto le dice a SQLAlchemy que pase el valor predeterminado como parte de la CREATE TABLE
declaración.
Por ejemplo, si escribe un script ad hoc en esta tabla, usar server_default
significa que no tendrá que preocuparse por agregar manualmente una llamada de marca de tiempo a su script; la base de datos lo configurará automáticamente.
Comprensión de SQLAlchemy's onupdate
/server_onupdate
SQLAlchemy también soporta onupdate
de manera que en cualquier momento se actualiza la fila se inserta un nuevo orden de llegada. Nuevamente, es mejor decirle a la base de datos que calcule la marca de tiempo en sí:
from sqlalchemy.sql import func
time_created = Column(DateTime(timezone=True), server_default=func.now())
time_updated = Column(DateTime(timezone=True), onupdate=func.now())
Hay un server_onupdate
parámetro, pero a diferencia server_default
, en realidad no establece nada en el lado del servidor. Simplemente le dice a SQLalchemy que su base de datos cambiará la columna cuando ocurra una actualización (quizás haya creado un disparador en la columna ), por lo que SQLAlchemy le pedirá el valor de retorno para que pueda actualizar el objeto correspondiente.
Otro potencial problema:
Es posible que se sorprenda al notar que si realiza varios cambios dentro de una sola transacción, todos tienen la misma marca de tiempo. Esto se debe a que el estándar SQL especifica que CURRENT_TIMESTAMP
devuelve valores basados en el inicio de la transacción.
PostgreSQL ofrece la no-estándar SQL statement_timestamp()
y clock_timestamp()
el que hacer el cambio dentro de una transacción. Documentos aquí: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
Marca de tiempo UTC
Si desea utilizar las marcas de tiempo UTC, un cabo de aplicación para func.utcnow()
se proporciona en la documentación SQLAlchemy . Sin embargo, debe proporcionar funciones específicas del controlador apropiadas por su cuenta.