Este equipo especializado despúes de algunos días de trabajo y de juntar de información, hallamos la respuesta, esperamos que te sea de utilidad para tu proyecto.
Solución:
Calcule las marcas de tiempo dentro de su base de datos, no de su cliente
Por cordura, probablemente quiera tener todos datetimes
calculado por su servidor DB, en lugar del servidor de aplicaciones. El cálculo de la marca de tiempo en la aplicación puede generar problemas porque la latencia de la red es variable, los clientes experimentan una desviación del reloj ligeramente diferente y, en ocasiones, diferentes lenguajes de programación calculan el tiempo de forma 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 en sí.
Utilice SQLALchemy 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 usar server_default
en vez de default
. Esto le dice a SQLAlchemy que pase el valor predeterminado como parte del CREATE TABLE
declaración.
Por ejemplo, si escribe un script ad hoc en esta tabla, utilizando server_default
significa que no tendrá que preocuparse por agregar manualmente una llamada de marca de tiempo a su secuencia de comandos: la base de datos la configurará automáticamente.
Comprensión de SQLAlchemy onupdate
/server_onupdate
SQLAlchemy también admite onupdate
para que cada vez que se actualice la fila, inserte una nueva marca de tiempo. 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 servidor. Simplemente le dice a SQLalchemy que su base de datos cambiará la columna cuando ocurra una actualización (tal vez creó un disparador en la columna), por lo que SQLAlchemy le pedirá el valor de retorno para que pueda actualizar el objeto correspondiente.
Otro problema potencial:
Es posible que se sorprenda al notar que si realiza un montón de cambios en una sola transacción, todos tienen la misma marca de tiempo. Eso es porque el estándar SQL especifica que CURRENT_TIMESTAMP
devuelve valores basados en el inicio de la transacción.
PostgreSQL proporciona el estándar no SQL statement_timestamp()
y clock_timestamp()
cual hacer cambiar 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 marcas de tiempo UTC, un trozo de implementación para func.utcnow()
se proporciona en la documentación de SQLAlchemy. Sin embargo, debe proporcionar las funciones específicas del controlador adecuadas por su cuenta.
DateTime
no tiene un valor predeterminado key como entrada. El valor por defecto key debe ser una entrada para el Column
función. Prueba esto:
import datetime
from sqlalchemy import Column, Integer, DateTime
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Test(Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
created_date = Column(DateTime, default=datetime.datetime.utcnow)
También puede usar la función incorporada sqlalchemy por defecto DateTime
from sqlalchemy.sql import func
DT = Column(DateTime(timezone=True), default=func.now())
Agradecemos que desees confirmar nuestra función añadiendo un comentario y dejando una puntuación te damos las gracias.