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'


Если я использую целочисленный тип, я могу установить значение по умолчанию. Что происходит?

889   6  

6 ответов:

DateTime нет ключа по умолчанию в качестве входных данных. Ключ по умолчанию должен быть входом в

вычислить временные метки в вашей БД, а не ваш клиент

для здравомыслия, вы, вероятно, хотите иметь все datetimes вычисляется вашим сервером БД, а не сервером приложений. Вычисление метки времени в приложении может привести к проблемам, так как задержка сети является переменной, клиенты испытывают немного другой дрейф часов, а различные языки программирования иногда вычисляют время немного по-разному.

SQLAlchemy позволяет сделать это с помощью передает func.now() или func.current_timestamp() (они являются псевдонимами друг друга), который говорит БД, чтобы вычислить саму метку времени.

использовать с SQLAlchemy это server_default

кроме того, для значения по умолчанию, когда вы уже сообщаете БД для вычисления значения, обычно лучше использовать server_default вместо default. Это говорит SQLAlchemy передать значение по умолчанию как часть CREATE TABLE заявление.

например, если вы пишете специальный скрипт для этой таблицы, используя server_default означает, что вам не нужно будет беспокоиться о ручном добавлении вызова timestamp к вашему скрипту-база данных установит его автоматически.

понимание с SQLAlchemy это 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(), который do изменения в рамках транзакции. Документы здесь: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT

UTC 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

    Ничего не найдено.