python - SQLAlchemy 和 SQL Server 日期时间字段溢出

标签 python sql-server sqlalchemy

我正在使用 SQLAlchemy 连接到 SQL Server 数据库。

我正在尝试从 python 脚本将对象插入到表中,但失败了。我收到错误:

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

看起来这是由以下日期时间对象引起的:

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

...那是 214 年 7 月 21 日

SQL Server 表中对应的日期时间字段的类型为 datetime2。

看起来从 python/SQLAlchemy 到 SQL Server 的转换并未在年初值中添加“0”。我通过以下事实证实了这一点:我可以使用带或不带前导“0”的 INSERT 语句手动将此日期添加到 SQL Server。

有没有办法强制日期的年份部分采用正确的格式?或者这是由其他原因引起的?

更新: 来自 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)

但我仍然遇到与以前相同的错误。

最佳答案

The corresponding date time field in the SQL Server table is of type datetime2.

SQL Alchemy 是否仍会将该值构建为 DATETIME 类型,而不考虑目标表中的相应类型?

datetime T-SQL:

Date range: January 1, 1753, through December 31, 9999:

另一个原因,似乎是问题的根源,与 ODBC 和 DATETIME2 有关: error 22008: Datetime field overflow when inserting a record with datetime2 field via ODBC

Earlier ODBC drivers for SQL Server could infer the server type (datetime or smalldatetime) from the scale (which had to be 0 or 3) and so could be more relaxed than SQL Server 2008 Native Client. The default scale for OdbcParameter is 0, and so earlier drivers could assume the server type must be smalldatetime and ignore any fractional seconds. With the introduction of datetime2 and a user defined scale of between 0 and 7 the driver can no longer infer the type from the scale and has to default to the richest type, datetime2. When the actual server type is not datetime2 there will be a server side conversion from datetime2 to the actual server type. I apologise for the invonvenience this has caused you, but we had little choice and the new behavior is documented.

看来 ODBC,从 SQL Server 2008 版本开始,在内部更改了 DATETIME2 的比例。

我建议听从this thread的建议并从 ODBC 切换到 native 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)

关于python - SQLAlchemy 和 SQL Server 日期时间字段溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54789614/

相关文章:

python - 使用 matplotlib 和 numpy 对图像应用复杂的变换

sql-server - 在 mssql 中使用 LastIndexOf 和 SubString

python - 按 OneToMany Elixir 关系的计数排序

python - Twisted + SQLAlchemy 和最好的方法

python - sklearn "transport"训练模型的最佳实践

python - 使用多个预测变量的逻辑回归

python - 将Dataframe写入ODS格式

sql-server - 如何在 SQL Server 中启用批量权限

sql-server - 将数据库从一个 SQL Server 导出到另一个 SQL Server

python - SQLAlchemy - 从表定义中删除列