SQLAlchemy по умолчанию DateTime
Это моя декларативная модель:
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)
однако, когда я пытаюсь импортировать этот модуль, я получаю эту ошибку:
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'
Если я использую целочисленный тип, я могу установить значение по умолчанию. Что происходит?
6 ответов:
вычислить временные метки в вашей БД, а не ваш клиент
для здравомыслия, вы, вероятно, хотите иметь все
datetimesвычисляется вашим сервером БД, а не сервером приложений. Вычисление метки времени в приложении может привести к проблемам, так как задержка сети является переменной, клиенты испытывают немного другой дрейф часов, а различные языки программирования иногда вычисляют время немного по-разному.SQLAlchemy позволяет сделать это с помощью передает
func.now()илиfunc.current_timestamp()(они являются псевдонимами друг друга), который говорит БД, чтобы вычислить саму метку времени.использовать с SQLAlchemy это
server_defaultкроме того, для значения по умолчанию, когда вы уже сообщаете БД для вычисления значения, обычно лучше использовать
server_defaultвместоdefault. Это говорит SQLAlchemy передать значение по умолчанию как частьCREATE TABLEзаявление.например, если вы пишете специальный скрипт для этой таблицы, используя
server_defaultозначает, что вам не нужно будет беспокоиться о ручном добавлении вызова timestamp к вашему скрипту-база данных установит его автоматически.понимание с SQLAlchemy это
onupdate/server_onupdateSQLAlchemy также поддерживает
onupdateтак что каждый раз, когда строка обновляется, он вставляет новую метку. Опять же, лучше всего сказать БД, чтобы вычислить саму метку времени:from sqlalchemy.sql import func time_created = Column(DateTime(timezone=True), server_default=func.now()) time_updated = Column(DateTime(timezone=True), onupdate=func.now())есть
server_onupdateпараметр, но в отличие отserver_default, на самом деле он ничего не устанавливает на сервере. Он просто говорит SQLalchemy, что ваша база данных изменит столбец, когда произойдет обновление (возможно, вы создали триггер на колонки), поэтому SQLAlchemy запросит возвращаемое значение, чтобы он мог обновить соответствующий объект.еще один потенциальный попался:
вы можете быть удивлены, заметив, что если вы сделаете кучу изменений в течение одна транзакция, все они имеют одинаковую метку времени. Это потому, что стандарт SQL указывает, что
CURRENT_TIMESTAMPвозвращает значения, основанные на начале транзакции.PostgreSQL предоставляет не SQL-стандарт
statement_timestamp()иclock_timestamp(), который do изменения в рамках транзакции. Документы здесь: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENTUTC timestamp
если вы хотите чтобы использовать временные метки UTC, заглушка реализации для
func.utcnow()находится в документация по SQLAlchemy. Однако вам необходимо самостоятельно предоставить соответствующие функции для конкретных драйверов.
вы также можете использовать встроенную функцию sqlalchemy для DateTime по умолчанию
from sqlalchemy.sql import func DT = Column(DateTime(timezone=True), default=func.now())
The
defaultпараметр ключевого слова должен быть задан объекту столбца.пример:
Column(u'timestamp', TIMESTAMP(timezone=True), primary_key=False, nullable=False, default=time_now),значение по умолчанию может быть вызываемым, которое здесь я определил следующим образом.
from pytz import timezone from datetime import datetime UTC = timezone('UTC') def time_now(): return datetime.now(UTC)
[Введите описание ссылки здесь][1]
вы, вероятно, хотите использовать onupdate=datetime.сейчас так что обновления также изменить last_updated
согласно документации PostgreSQL,https://www.postgresql.org/docs/9.6/static/functions-datetime.html
now, CURRENT_TIMESTAMP, LOCALTIMESTAMP return the time of transaction.Это считается особенностью: цель состоит в том, чтобы разрешить один транзакция должна иметь последовательное представление о "текущем" времени, так что несколько модификаций в рамках одной транзакции несут одно и то же время печать.
вы можете использовать statement_timestamp или clock_timestamp если вы не хотите, чтобы метка времени транзакции.
statement_timestamp ()
возвращает время начала текущего оператора (более конкретно, время получения последнего командного сообщения от клиента). statement_timestamp
clock_timestamp ()
возвращает фактическое текущее время, и поэтому его значение изменяется даже в одна команда SQL.
Comments