【问题标题】:SQL Server 2016 & Python 3.6.4 Data Entry ErrorSQL Server 2016 和 Python 3.6.4 数据输入错误
【发布时间】:2018-07-17 15:42:53
【问题描述】:

我目前正在为 SQL Server 2016 数据库中的一些查找表自动输入数据。一般来说,我对 SQL 相当陌生,但在 Python 方面有几年的经验。我的问题是,如果我插入数据的其中一个表中的每一列都没有值,它会向我抛出以下错误消息。

pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Implicit conversion from data type smalldatetime to int is not allowed. Use the CONVERT function to run this query. (257) (SQLExecDirectW); [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Statement(s) could not be prepared. (8180)')

现在解释一下。 我正在从 excel 文件中提取数据并将它们转储/更改为每行的元组(如下所示)。

Python 打印输出

Extracting data from AE60 to AJ66
('Item 1', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1)
('Item 2', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)
('Item 3', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)
('Item 4', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)
('Item 5', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)
('Item 6', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)
('Item 7', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)
INSERT INTO product.ProductFamily VALUES (?,?,?,?,?,?);

现在,我将通过以下行将这些插入到数据库中。

pyodbc cursor.execute()

cursor.execute(finstr, args)

其中 finstr 是 Python 打印输出的最后一行中的 SQL 代码,args 是 SQL 代码上方的任何一个元组。

现在,如果我要插入第一个元组,它对每一列都有一个值(即没有 None),那么我不会收到任何错误,一切都很好。但是,如果我要在其下方插入任何其他 6 个具有 None 值的元组,我会收到上述错误。相关表的 SQL 代码如下所示。

CREATE TABLE product.ProductFamily 
( ProductFamilyID  int IDENTITY(1,1) PRIMARY KEY,
  FamilyName  varchar(60) NOT NULL,
  Active bit NOT NULL, 
  DateCreated datetime NOT NULL,
  CreatedBy int NOT NULL,
  DateModified datetime,
  ModifiedBy int
) 

我们可以看到最后两列可以为空,因为它们是默认设置的,我读过 Python 的 None 类型被转换为 null 通过pyodbc。任何地方也没有“smalldatetime”字段的实例,所以这个问题非常令人困惑。

【问题讨论】:

  • 尝试在插入语句中使用字段列表来确认数据元素是否正确关联,例如INSERT INTO product.ProductFamily (FamilyName, Active, DateCreated, CreatedBy, DateModified, ModifiedBy) VALUES (?,?,?,?,?,?); 另外,作为双重检查,转储您的“Args”并确保元素的顺序没有发生任何随机事件。

标签: sql-server python-3.x pyodbc


【解决方案1】:

在 INSERT 中指定列列表 使用正确的 ODBC 驱动程序将解决此问题。 Windows 附带的“SQL Server”驱动程序已经很老了。

这是一个再现:

import csv
import datetime
import pyodbc

#sql_connection = 'DRIVER={ODBC Driver 13 for SQL Server};Server=localhost;Database=tempdb;Trusted_Connection=YES'

sql_connection = 'DRIVER={SQL Server};Server=(local);Database=tempdb;Trusted_Connection=YES'

connection = pyodbc.connect(sql_connection, autocommit=True)

connection.execute("if not exists (select * from sys.schemas where name = 'production') exec('create schema production') ")

connection.execute('drop table if exists production.ProductFamily')

sql = """
CREATE TABLE production.ProductFamily 
( ProductFamilyID  int IDENTITY(1,1) PRIMARY KEY,
  FamilyName  varchar(60) NOT NULL,
  Active bit NOT NULL, 
  DateCreated datetime NOT NULL,
  CreatedBy int NOT NULL,
  DateModified datetime,
  ModifiedBy int
)  """


connection.execute(sql)

sql = 'INSERT INTO production.ProductFamily(FamilyName,Active,DateCreated,CreatedBy,DateModified,ModifiedBy) VALUES (?,?,?,?,?,?);'
cursor = connection.cursor()
cursor.execute(sql,'Item 1', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1)
cursor.execute(sql,'Item 2', 1, datetime.datetime(2018, 7, 17, 11, 14, 48, 733561), 1, None, None)

print('done')

【讨论】:

  • 谢谢,更换驱动程序完美,不敢相信这是唯一的问题!
猜你喜欢
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 2014-10-13
  • 1970-01-01
  • 2017-09-08
相关资源
最近更新 更多