Обчисліть часові позначки у вашій БД, а не у клієнта
Для розуму ви, мабуть, хочете мати всіх datetimes
обчислено вашим сервером БД, а не сервером додатків. Обчислення часової позначки в додатку може призвести до проблем, оскільки затримка в мережі мінлива, клієнти відчувають дещо інший рух годинника, а різні мови програмування час від часу обчислюють час дещо інакше.
SQLAlchemy дозволяє зробити це шляхом передачі func.now()
або func.current_timestamp()
(вони є псевдонімами один одного), що повідомляє БД обчислити саму часову марку.
Використовуйте SQLALchemy 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 міститься заголовок реалізації . Вам потрібно забезпечити відповідні функції, характерні для драйвера, самостійно.