(fast_executemany = True) 错误“[ODBC Driver 17 for SQL Server]强制转换规范的字符值无效 (0) (SQLExecute)')”

Dan*_*con 5 python sql-server pyodbc executemany

我正在使用 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()
Run Code Online (Sandbox Code Playgroud)

它工作正常,但如果我取消注释该行cursor.fast_executemany = True,则会出现以下错误:

('22018', '[22018] [Microsoft][ODBC Driver 17 for SQL Server]Invalid character value for cast specification (0) (SQLExecute)')
Run Code Online (Sandbox Code Playgroud)

下面是我的表:

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
)
Run Code Online (Sandbox Code Playgroud)

格式有问题吗?我在使用时缺少什么cursor.fast_executemany = True

Gor*_*son 7

使用fast_executemany = False(默认),pyodbc 每行发送一个 INSERT 并将参数值直接传递到 SQL Server。当 SQL Server 遇到空字符串作为datetime列的参数值时,该值将被解释为1900-01-01 00:00:00

使用fast_executemany = True,pyodbc 将所有参数值打包到称为参数数组的二进制结构中,并将其与 SQL 命令文本一起传递,本质上是在一个步骤中执行所有行的 INSERT。但是,对于列的空字符串,SQL Server ODBC 驱动程序不会做出与 T-SQL 相同的假设datetime,因此您会收到错误。

[22018] [Microsoft][ODBC Driver 17 for SQL Server]转换规范的字符值无效 (0) (SQLExecute)

datetimeTL;DR:如果您使用 ,则可以将空字符串作为列的参数值传递fast_executemany = False,但如果您使用 ,则不行fast_executemany = True


小智 1

您可以使用它将所有空字符串转换为元组中的 None 值。这不仅适用于datetime字段。

tuples = [(a, *(b if b else None for b in rest)) for a, *rest in tuples]
Run Code Online (Sandbox Code Playgroud)