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 = 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 uso un tipo Integer, puedo establecer un valor predeterminado. ¿Que esta pasando?
Esto no debe usarse. utcnow es una marca de tiempo ingenua en la zona horaria UTC, sin embargo, es probable que las marcas de tiempo ingenuas se interpreten en la zona horaria local.
– Antti Haapala — Слава Україні
6 de octubre de 2016 a las 7:33
Sé que esta pregunta se hizo hace mucho tiempo, pero creo que su respuesta debe cambiarse por la que proporcionó @Jeff Widman, ya que la otra usará la fecha y hora de “compilación” cuando se define la clase de tabla en lugar de cuando se crea el registro. Si está AFK, al menos este comentario proporcionará una advertencia para que otros revisen cuidadosamente los comentarios para cada pregunta.
– David
21 de febrero de 2019 a las 21:12
Jeff Widman
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í:
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 gatillo en la columna ), por lo que SQLAlchemy solicitará el valor devuelto para poder 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.
Si desea utilizar marcas de tiempo UTC, un trozo de implementación para func.utcnow() se proporciona en Documentación de SQLAlchemy. Sin embargo, debe proporcionar las funciones específicas del controlador adecuadas por su cuenta.
Estoy totalmente de acuerdo contigo. Sin embargo, mi configuración no funciona. “` clase TimestampMixin(objeto): created_at = Column(‘created_at’, DateTime(timezone=True), default=func.now()) updated_at = Column(‘updated_at’, DateTime(timezone=True), default=func .now(), onupdate=func.now()) “` Emití una declaración de creación y actualización con 1 segundo de diferencia. Los dos valores para created_at y updated_at son siempre los mismos.
– Khanh Hua
8 de enero de 2016 a las 2:16
Vi que ahora hay una manera de decirle a Postgres que use la hora actual, no solo la hora de inicio de la transacción… está en los documentos de Postgres
–Jeff Widman
5 mayo 2016 a las 22:03
¿Hay un func.utcnow() o algo así?
– yerassyl
19 de abril de 2017 a las 4:47
@JeffWidman: ¿Tenemos una implementación de mysql para utcnow? Yo en documentación solo mssql y postreg
– Java Sa
29 de noviembre de 2017 a las 15:13
server_default=func.now() funcionó para mí, pero onupdate=func.now() no. Intentó onupdate=datetime.datetime.utcnow (sin paréntesis), eso tampoco ayudó
– Vikas Prasad
16 de agosto de 2018 a las 15:03
PearsonArteFoto
DateTime no tiene una clave predeterminada como entrada. La clave predeterminada 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)
Esto no está bien. La marca de tiempo en la carga del modelo se utilizará para todos los registros nuevos en lugar de la hora en que se agrega el registro.
– SkyLeach
9 de febrero de 2016 a las 16:18
@SkyLeach Este código es correcto, puedes probarlo aquí: pastebin.com/VLyWktUn . datetime.datetime.utcnow parece llamado como devolución de llamada.
– bux
04/03/2016 a las 14:55
Usé esta respuesta, pero la marca de tiempo en la carga del modelo se usa para todos los registros nuevos.
– scottydelta
26 de enero de 2017 a las 2:20
@scottdelta: asegúrese de no estar usando default=datetime.datetime.utcnow(); quieres pasar el utcnow función, no el resultado de evaluarlo en la carga del módulo.
– disfunción
22 de febrero de 2017 a las 15:54
Todavía no funcionó para mí. El enfoque de jeff-widman funcionó para mí: from sqlalchemy.sql import func; created_date = Column(DateTime(timezone=True), server_default=func.now()
– gracias
21 de enero de 2020 a las 10:18
QWERTY
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())
También puedes usar server_default en vez de default por lo tanto, el valor será manejado por la propia base de datos.
– rgtk
6 de junio de 2015 a las 14:55
No se ejecuta func.now() cuando se define el descriptor, por lo que todos los modelos/hijos (si se trata de una clase base) tendrán el mismo valor de DT. Al pasar una referencia de función como ‘datetime.datetime.utcnow’, se ejecuta por separado para cada uno. Esto es crucial para las propiedades ‘creadas’ o ‘actualizadas’.
– Tormenta de metal
26 de febrero de 2016 a las 1:27
@Metalstorm No, esto es correcto. sqlalchemy.sql.func es un caso especial que devuelve una instancia de sqlalchemy.sql.functions.now, no la hora actual. docs.sqlalchemy.org/en/latest/core/…
– Kris Hardy
15/03/2016 a las 22:25
Que hace timezone=True ¿hacer?
– ChaimG
23 de junio de 2016 a las 1:41
@self, Desde la documentación: “Si es Verdadero, y es compatible con el backend, producirá ‘TIMESTAMP WITH TIMEZONE’. Para los backends que no admiten marcas de tiempo conscientes de la zona horaria, no tiene efecto. .
– ChaimG
23 de junio de 2016 a las 1:45
usuario3389572
Es probable que desee utilizar onupdate=datetime.now para que las ACTUALIZACIONES también cambien el last_updated campo.
SQLAlchemy tiene dos valores predeterminados para las funciones ejecutadas de Python.
default establece el valor en INSERT, solo una vez
onupdate establece el valor de la invocable resultado en ACTUALIZAR también.
Raúl Mishra
Utilizando el default parámetro con datetime.now:
from sqlalchemy import Column, Integer, DateTime
from datetime import datetime
class Test(Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
Formatee su código correctamente y puede explicar un poco cómo resuelve el problema.
– swag2198
7 de mayo de 2021 a las 6:32
default=datetime.now en la columna, ahorrará tiempo al insertar los registros.
– Raúl Mishra
hace 2 días
los default El parámetro de palabra clave se debe dar al objeto de columna.
now, CURRENT_TIMESTAMP, LOCALTIMESTAMP devolver la hora de la transacción
Esto se considera una característica: la intención es permitir que una sola transacción tenga una noción consistente de la hora “actual”, de modo que múltiples modificaciones dentro de la misma transacción lleven 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). declaración_marca de tiempo
clock_timestamp()
devuelve la hora actual real y, por lo tanto, su valor cambia incluso dentro de un solo comando SQL.
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información
Esto no debe usarse. utcnow es una marca de tiempo ingenua en la zona horaria UTC, sin embargo, es probable que las marcas de tiempo ingenuas se interpreten en la zona horaria local.
– Antti Haapala — Слава Україні
6 de octubre de 2016 a las 7:33
Sé que esta pregunta se hizo hace mucho tiempo, pero creo que su respuesta debe cambiarse por la que proporcionó @Jeff Widman, ya que la otra usará la fecha y hora de “compilación” cuando se define la clase de tabla en lugar de cuando se crea el registro. Si está AFK, al menos este comentario proporcionará una advertencia para que otros revisen cuidadosamente los comentarios para cada pregunta.
– David
21 de febrero de 2019 a las 21:12