Вставить строку со столбцом значения по умолчанию в sqlalchemy - PullRequest
0 голосов
/ 03 апреля 2020

Я пишу программу, которая использует базу данных с sqlalchemy в качестве клиента.

Вот одна из моих таблиц

class DownloadRecord(Base):
    __tablename__ = "DownloadRecords"
    id = Column("Id", Integer, primary_key=True, autoincrement=True)

    download_name = Column("DownloadName", Unicode, nullable=False)
    download_date = Column(
        "DownloadDate", DateTime, default=datetime.datetime.utcnow, nullable=False
    )

столбец download_date определен со значением по умолчанию, и здесь, и в таблице на стороне сервера. Вот определение столбца на сервере ms sql

DownloadDate DATETIME NOT NULL DEFAULT GETDATE()

, однако я пытаюсь добавить запись DownloadRecord(download_name="new_download_name") и получаю следующее исключение.

sqlalchemy .ex c .IntegrityError: (pyodb c .IntegrityError) ('23000', "[23000] [Microsoft] [SQL Собственный клиент сервера 11.0] [SQL Сервер] Невозможно вставить значение NULL в столбец 'DownloadDate', таблица 'DownloadRecords'; столбец не допускает пустые значения. INSERT завершается неудачно. (515) (SQLExecDirectW); [23000] [Microsoft] [SQL Собственный клиент сервера 11.0] [SQL Сервер] Оператор был прекращено. (3621) ") [SQL: ВСТАВИТЬ INTO [DownloadRecords] ([DownloadName], [DownloadDate]) ВЫХОД вставлен. [Id] ЗНАЧЕНИЯ (?,?)] [параметры: (" имя_нового_загрузки ", нет)]

Я также пытался сделать этот столбец обнуляемым, но когда я добавил новую строку, столбец DownloadDate был пустым. Как мне сделать так, чтобы оно автоматически использовало значение по умолчанию?

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Поиск Я нашел некоторых людей, исправленных с помощью аргумента server_default . Но это делает сервер базы данных ответственным за присвоение значения.

download_date = Column(
    "DownloadDate", DateTime, server_default=text('NOW()'), nullable=False
)

Также в соответствии с документацией SQLAlchemy , класс ColumnDefault эквивалентен, и он также может работать:

download_date = Column(
    "DownloadDate", DateTime, ColumnDefault(datetime.datetime.utcnow()), nullable=False
)

Но для этого используется скаляр вместо вызываемого .

Надеюсь, это сработает.

0 голосов
/ 03 апреля 2020

Проблема заключается в несовместимости между типом столбца DownloadDate и типом значения, которое вы задаете в качестве значения по умолчанию на стороне клиента.

Используемый вами тип DateTime (на как на стороне сервера, так и на стороне клиента).

Однако в следующем коде:

Column("DownloadDate", DateTime, default=datetime.datetime.utcnow, nullable=False)

возвращаемое значение datetime.datetime.utcnow() является объектом с поддержкой часового пояса, а SQL сервером DateTime не так.

Я вижу два возможных решения:

  1. Измените значение по умолчанию на вызываемый, который возвращает объект datetime, который не распознает часовой пояс .

  2. Измените тип столбца DownloadDate на тип с указанием часового пояса. Вы можете использовать SQL Server datetimeoffset на стороне сервера и DATETIMEOFFSET SQLAlchemy на стороне клиента.

Взгляните на документы Microsoft по дате и времени введите для полной справки.

В другой заметке рассмотрите возможность перехода к дизайну первого кода, где вы определяете свою схему в одном месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...