首页 > 解决方案 > df.to_sql 突然给出关于列不允许空值的错误

问题描述

我有一个奇怪的问题。

我有一个将数据框附加到 sql 表的 python 脚本。

我已经运行这个脚本几个月没有问题,但突然之间它给了我关于由于空值而无法插入特定列的问题。

问题是,数据框中没有 null 或 na 值。

我插入的表有一个身份 ID 列,但这在过去从来都不是问题......我正在努力理解这里可能发生的事情,任何建议都将不胜感激,我正在使用的代码如下。

    quoted = urllib.parse.quote_plus('DRIVER={ODBC Driver 17 for SQL Server}; SERVER= 
    servername; DATABASE=databasename;   Trusted_Connection=yes')
    engine = create_engine('mssql+pyodbc:///?odbc_connect={}'.format(quoted))
   df.to_sql('table', engine, if_exists = 'append', index = False)

错误信息如下:

IntegrityError: (pyodbc.IntegrityError) ('23000', "[23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]无法将 NULL 值插入列 'Column_Name'、表 'databasename.dbo.table' ; 列不允许空值。更新失败。(515) (SQLExecDirectW); [23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]语句已终止。(3621)")

错误消息上显示的实际行:

[SQL: INSERT INTO [Schedule] ([Asset_ID], [Part_ID], [Shift_ID], [Quantity], [Containers], [SortOrder], [Status_ID], [ProductionDate], [CreatedDate]) 值 (?, ? , ?, ?, ?, ?, ?, ?, ?)] [参数:((84, 348, 1, 30, 21, 1, 7, datetime.datetime(2021, 8, 9, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)), (84, 348, 4, 30, 21, 1, 7, datetime.datetime(2021, 8, 10, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)), (84, 348, 7, 30, 10, 1, 7, datetime.datetime(2021, 8, 11, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)), (79, 335, 7, 10, 42, 2, 7, datetime.datetime(2021, 8, 11, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)), (79, 335, 10, 10, 71, 1, 7, datetime.datetime(2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)), (79, 336, 10, 56, 1, 2, 7, datetime.datetime(2021, 8, 12, 0, 0),约会时间。datetime(2021, 8, 5, 8, 51, 44, 565000)), (79, 336, 13, 56, 10, 1, 7, datetime.datetime(2021, 8, 13, 0, 0), 日期时间。 datetime(2021, 8, 5, 8, 51, 44, 565000)), (26, 278, 1, 30, 54, 1, 7, datetime.datetime(2021, 8, 9, 0, 0), 日期时间。 datetime(2021, 8, 5, 8, 51, 44, 565000)) ... 显示 264 个总绑定参数集中的 10 个 ... (55, 248, 10, 90, 2, 1, 7, datetime.datetime( 2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)), (55, 248, 10, 90, 6, 4, 7, datetime.datetime( 2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5, 8, 51, 44, 565000)))]显示 264 个总绑定参数集中的 10 个 ... (55, 248, 10, 90, 2, 1, 7, datetime.datetime(2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5) , 8, 51, 44, 565000)), (55, 248, 10, 90, 6, 4, 7, datetime.datetime(2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5) , 8, 51, 44, 565000)))]显示 264 个总绑定参数集中的 10 个 ... (55, 248, 10, 90, 2, 1, 7, datetime.datetime(2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5) , 8, 51, 44, 565000)), (55, 248, 10, 90, 6, 4, 7, datetime.datetime(2021, 8, 12, 0, 0), datetime.datetime(2021, 8, 5) , 8, 51, 44, 565000)))]

标签: pythonsqlpandassqlalchemy

解决方案


所以这最终成为一个数据完整性问题,与空行完全无关。

本质上,一张表有两个 ID 指代基本相同的事物,其中一个显然已过时。由于其他限制,过时的项目在尝试上传时出错。


推荐阅读