Переполнение полей SQLAlchemy и SQL Server Datetime - PullRequest
0 голосов
/ 20 февраля 2019

Я использую SQLAlchemy для подключения к базе данных SQL Server.

Я пытаюсь вставить объект в таблицу из моего скрипта на python, и он не работает.Я получаю сообщение об ошибке:

(pyodbc.DataError) ('22008', '[22008] [Microsoft][ODBC SQL Server Driver]Datetime field overflow (0) (SQLExecDirectW)')

Похоже, что это вызвано следующим объектом datetime:

datetime.datetime(214, 7, 21, 0, 0)

... это 21 июля 214

Соответствующее поле даты и времени в таблице SQL Server имеет тип datetime2.

Похоже, что преобразование из python / SQLAlchemy в SQL Server не добавляет '0' к началу значения года.Я подтвердил это тем фактом, что я могу вручную добавить эту дату в SQL Server, используя инструкцию INSERT с и без начального «0».

Есть ли способ принудительно указать часть года в датев правильный формат?Или это вызвано чем-то еще?

ОБНОВЛЕНИЕ: С https://docs.sqlalchemy.org/en/latest/dialects/mssql.html Я обнаружил, что вы можете указать тип столбца как DATETIME2 (для MS SQL)и я соответственно обновил сопоставление объектов.

Так что раньше это было:

from base import Base
from sqlalchemy import Column, Integer, String, Numeric, DateTime

class Results(Base):
    __tablename__ = 'Result'

    dateTimeMinValue = Column(DateTime)
    dateTimeMaxValue = Column(DateTime)

И я теперь обновил его до:

from base import Base
from sqlalchemy import Column, Integer, String, Numeric
from sqlalchemy.dialects.mssql import DATETIME2

class Results(Base):
    __tablename__ = 'Result'

    dateTimeMinValue = Column(DATETIME2)
    dateTimeMaxValue = Column(DATETIME2)

Но япо-прежнему появляется та же ошибка, что и раньше.

1 Ответ

0 голосов
/ 22 февраля 2019

Соответствующее поле даты и времени в таблице SQL Server имеет тип datetime2.

Может ли быть так, что SQL Alchemy по-прежнему создает это значение как тип DATETIME без учета соответствующего типа втаблица назначения?

дата-время T-SQL:

Диапазон дат: с 1 января 1753 года по 31 декабря 9999 года:

Другая причина, которая, по-видимому, является корнем проблемы, связана с ODBC и DATETIME2: ошибка 22008: переполнение поля даты и времени при вставке записи с полем datetime2 через ODBC

Более ранние драйверы ODBC для SQL Server могли выводить тип сервера (datetime или smalldatetime) по шкале (которая должна была быть 0 или 3) и поэтому могли быть более непринужденными, чем собственный клиент SQL Server 2008.Масштаб по умолчанию для OdbcParameter равен 0, поэтому более ранние драйверы могли предполагать, что тип сервера должен быть smalldatetime, и игнорировать любые доли секунды. С введением datetime2 и пользовательской шкалы от 0 до 7 драйвер больше не может выводить тип из шкалы и должен по умолчанию использовать самый богатый тип datetime2.Если фактическим типом сервера не является datetime2, произойдет преобразование на стороне сервера из datetime2 в фактический тип сервера .Я прошу прощения за неудобства, которые это вызвало у вас, но у нас был небольшой выбор, и новое поведение задокументировано.

Так что, похоже, ODBC, начиная с выпуска SQL Server 2008, внутренне меняет масштаб DATETIME2,

Предлагаю последовать совету этого потока и перейти с ODBC на собственный клиент SQL Server:

import sqlalchemy as sql
connectionString = 'mssql+pyodbc://username:password@my_server/my_database_name?driver=SQL Server Native Client 10.0'
engine = sql.create_engine(connectionString)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...