我正在使用pyodbc中的(executemany(函数将数据填充到mssql数据库中。这是我的代码:
def populate_database(conn):
tuples = [
('2020-04-13 00:50:42', 'AirShoppingRQ', 'ALEY', '2020-05-23', '', '', 'BRU-BLQ', ''),
('2020-04-13 00:50:43', 'AirShoppingRQ', 'ALEY', '2021-01-23', '', '', 'LIS-STO', '')
]
query_string = 'INSERT INTO mytable VALUES (?,?,?,?,?,?,?,?)'
cursor = conn.cursor()
#cursor.fast_executemany = True
cursor.executemany(query_string, tuples)
cursor.commit()
它工作得很好,但如果我取消对cursor.fast_executemany = True
行的注释,那么我会得到以下错误:
('22018', '[22018] [Microsoft][ODBC Driver 17 for SQL Server]Invalid character value for cast specification (0) (SQLExecute)')
以下是我的表格:
CREATE TABLE [dbo].[mytable](
[field1] [datetime] NULL,
[field2] [varchar](50) NULL,
[field3] [varchar](20) NULL,
[field4] [datetime] NULL,
[field5] [datetime] NULL,
[field6] [varchar](20) NULL,
[field7] [varchar](40) NULL,
[field8] [varchar](40) NULL
)
格式有问题吗?使用cursor.fast_executemany = True
时缺少什么?
使用fast_executemany = False
(默认值(,pyodbc每行发送一个INSERT,并将参数值直接传递给SQL Server。当SQL Server遇到一个空字符串作为datetime
列的参数值时,该值将被解释为1900-01-01 00:00:00
。
使用fast_executemany = True
,pyodbc将所有参数值打包到一个名为参数数组的二进制结构中,并将其与SQL命令文本一起传递,实质上是在一个步骤中执行所有行的INSERT。但是,对于datetime
列的空字符串,SQL Server ODBC驱动程序并没有做出与T-SQL相同的假设,因此会出现错误。
〔22018〕〔Microsoft〕〔SQL Server的ODBC驱动程序17〕强制转换规范(0((SQLExecute(的字符值无效
TL;DR:如果使用fast_executemany = False
,则可以传递一个空字符串作为datetime
列的参数值,但如果使用fast_executemany = True
,则不能传递。
您可以使用它将元组中的所有空字符串转换为None值。这不仅适用于datetime
字段。
tuples = [(a, *(b if b else None for b in rest)) for a, *rest in tuples]