SQL Server 2016 & Python 3.6.4 数据输入错误

SQL Server 2016 & Python 3.6.4 Data Entry Error

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

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 文件中提取数据,并将它们 dumping/altering 放入每一行的元组中(如下所示)。

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 值,则会出现上述错误。 table 的 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 类型通过 pyodbc 转换为 null。在任何地方也没有 "smalldatetime" 字段的实例,所以这个问题非常令人困惑。

使用正确的 ODBC 驱动程序在 INSERT 中指定列列表将解决此问题。 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')