Вычислять метки времени в вашей БД, а не в вашем клиенте
Для здравомыслия, вы, вероятно, хотите, чтобы все datetimes
вычислялись вашим сервером БД, а не сервером приложений. Вычисление метки времени в приложении может привести к проблемам, поскольку задержка в сети является переменной, клиенты испытывают несколько различный сдвиг тактовой частоты, а разные языки программирования иногда вычисляют время немного по-разному.
SQLAlchemy позволяет вам сделать это, передав func.now()
или func.current_timestamp()
(они являются псевдонимами друг друга), который указывает БД рассчитать саму метку времени.
Используйте SQLALchemy's server_default
Кроме того, для значения по умолчанию, когда вы уже говорите БД для вычисления значения, обычно лучше использовать server_default
вместо default
. Это говорит SQLAlchemy передать значение по умолчанию как часть CREATE TABLE
инструкции.
Например, если вы напишите специальный скрипт для этой таблицы, используя server_default
означает, что вам не нужно беспокоиться о ручном добавлении вызова метки времени в ваш скрипт - база данных установит его автоматически.
Понимание SQLAlchemy's onupdate
/server_onupdate
SQLAlchemy также поддерживает, 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()
которые делают изменения в рамках транзакции. Документы здесь: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
Метка времени UTC
Если вы хотите использовать метки времени UTC, заглушка для реализации func.utcnow()
предоставлена в документации SQLAlchemy . Вы должны предоставить соответствующие специфичные для драйвера функции самостоятельно, хотя.