primary current_timestamp auto_increment python date sqlalchemy

python - current_timestamp - SQLAlchemy predeterminado DateTime



sqlalchemy datetime (6)

Calcule las marcas de tiempo dentro de su DB, no su cliente

Para la cordura, es probable que desee tener todas las datetimes y datetimes calculadas por su servidor de base de datos, en lugar del servidor de aplicaciones. El cálculo de la marca de tiempo en la aplicación puede provocar problemas porque la latencia de la red es variable, los clientes experimentan variaciones de reloj ligeramente diferentes, y los diferentes lenguajes de programación ocasionalmente calculan el tiempo de forma ligeramente diferente.

SQLAlchemy le permite hacer esto pasando func.now() o func.now() (son alias uno del otro) que le dice al DB que calcule la marca de tiempo en sí.

Usar SQLALchemy''s server_default

Además, para un valor predeterminado donde ya le está diciendo al DB que calcule el valor, generalmente es mejor usar server_default lugar de default . Esto le dice a SQLAlchemy que pase el valor predeterminado como parte de la instrucción CREATE TABLE .

Por ejemplo, si escribe una secuencia de comandos ad hoc en esta tabla, usar server_default significa que no tendrá que preocuparse por agregar manualmente una marca de fecha y hora a su secuencia de comandos; la base de datos lo configurará automáticamente.

Comprender la onupdate de SQLAlchemy / 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 al DB que calcule la marca de tiempo en sí misma:

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 parámetro server_onupdate , pero a diferencia de 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 (quizás haya creado un activador en la columna ), por lo que SQLAlchemy le pedirá el valor de retorno para que pueda actualizar el objeto correspondiente.

Otro potencial gotcha:

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. Esto se debe a que el estándar SQL especifica que CURRENT_TIMESTAMP devuelve valores basados ​​en el inicio de la transacción.

PostgreSQL proporciona el estándar de tiempo de statement_timestamp() non-SQL statement_timestamp() y clock_timestamp() que cambian 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, se proporciona un trozo de implementación para func.utcnow() en la documentación de SQLAlchemy . Sin embargo, debe proporcionar las funciones específicas del controlador adecuadas por su cuenta.

Este es mi modelo declarativo:

import datetime from sqlalchemy import Column, Integer from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Test(Base): __tablename__ = ''test'' id = Column(Integer, primary_key=True) created_date = DateTime(default=datetime.datetime.utcnow)

Sin embargo, cuando intento importar este módulo, aparece este error:

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "orm/models2.py", line 37, in <module> class Test(Base): File "orm/models2.py", line 41, in Test created_date = sqlalchemy.DateTime(default=datetime.datetime.utcnow) TypeError: __init__() got an unexpected keyword argument ''default''

Si utilizo un tipo entero, puedo establecer un valor predeterminado. ¿Que esta pasando?


El parámetro de palabra clave default debe asignarse al objeto Columna.

Ejemplo:

Column(u''timestamp'', TIMESTAMP(timezone=True), primary_key=False, nullable=False, default=time_now),

El valor predeterminado puede ser invocable, que aquí definí como el siguiente.

from pytz import timezone from datetime import datetime UTC = timezone(''UTC'') def time_now(): return datetime.now(UTC)


Según la documentación de PostgreSQL, https://www.postgresql.org/docs/9.6/static/functions-datetime.html

now, CURRENT_TIMESTAMP, LOCALTIMESTAMP return the time of transaction.

Esto se considera una característica: la intención es permitir que una sola transacción tenga una noción coherente del tiempo "actual", de modo que las modificaciones múltiples dentro de la misma transacción tengan la misma marca de tiempo.

Es posible que desee utilizar statement_timestamp o clock_timestamp si no desea la marca de tiempo de la transacción.

statement_timestamp ()

devuelve la hora de inicio de la declaración actual (más específicamente, la hora de recepción del último mensaje de comando del cliente). statement_timestamp

clock_timestamp ()

devuelve la hora actual real, y por lo tanto su valor cambia incluso dentro de un solo comando SQL.


También puede usar la función sqlalchemy incorporada para DateTime por defecto

from sqlalchemy.sql import func DT = Column(DateTime(timezone=True), default=func.now())


[ingrese la descripción del enlace aquí] [1]

Es probable que desee utilizar onupdate = datetime.now para que UPDATE también cambie el último campo actualizado .

[1]: SQLAlchemy tiene dos valores predeterminados para las funciones ejecutadas por Python.

  • por defecto establece el valor en INSERT, solo una vez
  • onupdate también establece el valor del resultado invocable en ACTUALIZAR.

DateTime no tiene una clave predeterminada como entrada. La clave predeterminada debe ser una entrada a la función Column . 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)