"Invalid parameter type" (numpy.int64) 使用 executemany() 插入行时
"Invalid parameter type" (numpy.int64) when inserting rows with executemany()
我尝试向数据库中插入一堆数据
insert_list = [(1,1,1,1,1,1),(2,2,2,2,2,2),(3,3,3,3,3,3),....] #up to 10000 tuples in this list
conn = pyodbc.connect('DRIVER={FreeTDS};SERVER=xxxxx;DATABASE=xxxx;UID=xx;PWD=xx;TDS_Version=7.0')
cursor = conn.cursor()
sql = "insert into ScanEMAxEMAHistoryDay(SecurityNumber, EMA1, EMA2, CrossType, DayCross, IsLocalMinMax) values (?, ?, ?, ?, ?, ?)"
cursor.executemany(sql, insert_list)
cursor.executemany(sql, insert_list)
pyodbc.ProgrammingError: ('Invalid parameter type. param-index=4 param-type=numpy.int64', 'HY105')
减少到 100 个元组:
cursor.executemany(sql, insert_list[:100])
cursor.executemany(sql, insert_list[:100])
pyodbc.ProgrammingError: ('Invalid parameter type. param-index=4 param-type=numpy.int64', 'HY105')
cursor.executemany(sql, insert_list[:100])
减少到 5 个元组:
cursor.executemany(sql, insert_list[:5])
conn.commit()
这个可以插入数据库
我已经尝试:
sql = 'SET GLOBAL max_allowed_packet=50*1024*1024'
cursor.execute(sql)
在 excutemany() 之前,但它有一个错误:
pyodbc.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]'GLOBAL' is not a recognized SET option. (195) (SQLExecDirectW)")
我是怎么解决的。
谢谢。
您的问题不在于数据量 本身 ,而是您的一些元组包含 numpy.int64
不能直接用作参数值的值你的 SQL 声明。例如,
a = numpy.array([10, 11, 12], dtype=numpy.int64)
params = (1, 1, a[1], 1, 1, 1)
crsr.execute(sql, params)
会抛出
ProgrammingError: ('Invalid parameter type. param-index=2 param-type=numpy.int64', 'HY105')
因为第三个参数值是您的 numpy 数组 a
中的一个 numpy.int64
元素。使用 int()
转换该值将避免此问题:
a = numpy.array([10, 11, 12], dtype=numpy.int64)
params = (1, 1, int(a[1]), 1, 1, 1)
crsr.execute(sql, params)
顺便说一句,
的原因
sql = 'SET GLOBAL max_allowed_packet=50*1024*1024'
cursor.execute(sql)
没用是因为 max_allowed_packet
是一个 MySQL 设置,对 Microsoft SQL 服务器没有任何意义。
对于任何读到这篇文章的人来说,它让我感到困惑。
我最终的解决方案是将所有变量转换为 'str' 并且效果很好。
我和罗伯特一样;我将所有内容都转换为字符串。在我的例子中,它是我转换为字符串类型的 pandas 数据框:
data = pandas.read_json(...)
data.astype(str).to_sql(...)
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.astype.html
如果您检索的数据包含 URL,您可能会收到“未知协议”错误(或类似错误)。如果在转换为字符串类型后仍出现此错误,请尝试使用 StringIO
而不是 :
import requests
from io import StringIO
...
data = pandas.read_json(StringIO(response.text))
其中 response
是 requests
库中对象 Response
的实例,其属性 text
包含 json 文本数据。
我在使用 pyodbc
将参数传递到 SQL INSERT 语句时遇到了同样的错误。正如罗伯特所提到的,只需将变量转换为字符串即可。
示例:
语法 - str()
cursor.execute("INSERT INTO Table ([col1],[col2],[col3]...])VALUES(?,'test',?)", str(value1), str(value3))
我尝试向数据库中插入一堆数据
insert_list = [(1,1,1,1,1,1),(2,2,2,2,2,2),(3,3,3,3,3,3),....] #up to 10000 tuples in this list
conn = pyodbc.connect('DRIVER={FreeTDS};SERVER=xxxxx;DATABASE=xxxx;UID=xx;PWD=xx;TDS_Version=7.0')
cursor = conn.cursor()
sql = "insert into ScanEMAxEMAHistoryDay(SecurityNumber, EMA1, EMA2, CrossType, DayCross, IsLocalMinMax) values (?, ?, ?, ?, ?, ?)"
cursor.executemany(sql, insert_list)
cursor.executemany(sql, insert_list)
pyodbc.ProgrammingError: ('Invalid parameter type. param-index=4 param-type=numpy.int64', 'HY105')
减少到 100 个元组:
cursor.executemany(sql, insert_list[:100])
cursor.executemany(sql, insert_list[:100])
pyodbc.ProgrammingError: ('Invalid parameter type. param-index=4 param-type=numpy.int64', 'HY105') cursor.executemany(sql, insert_list[:100])
减少到 5 个元组:
cursor.executemany(sql, insert_list[:5])
conn.commit()
这个可以插入数据库
我已经尝试:
sql = 'SET GLOBAL max_allowed_packet=50*1024*1024'
cursor.execute(sql)
在 excutemany() 之前,但它有一个错误:
pyodbc.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]'GLOBAL' is not a recognized SET option. (195) (SQLExecDirectW)")
我是怎么解决的。
谢谢。
您的问题不在于数据量 本身 ,而是您的一些元组包含 numpy.int64
不能直接用作参数值的值你的 SQL 声明。例如,
a = numpy.array([10, 11, 12], dtype=numpy.int64)
params = (1, 1, a[1], 1, 1, 1)
crsr.execute(sql, params)
会抛出
ProgrammingError: ('Invalid parameter type. param-index=2 param-type=numpy.int64', 'HY105')
因为第三个参数值是您的 numpy 数组 a
中的一个 numpy.int64
元素。使用 int()
转换该值将避免此问题:
a = numpy.array([10, 11, 12], dtype=numpy.int64)
params = (1, 1, int(a[1]), 1, 1, 1)
crsr.execute(sql, params)
顺便说一句,
的原因sql = 'SET GLOBAL max_allowed_packet=50*1024*1024'
cursor.execute(sql)
没用是因为 max_allowed_packet
是一个 MySQL 设置,对 Microsoft SQL 服务器没有任何意义。
对于任何读到这篇文章的人来说,它让我感到困惑。
我最终的解决方案是将所有变量转换为 'str' 并且效果很好。
我和罗伯特一样;我将所有内容都转换为字符串。在我的例子中,它是我转换为字符串类型的 pandas 数据框:
data = pandas.read_json(...)
data.astype(str).to_sql(...)
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.astype.html
如果您检索的数据包含 URL,您可能会收到“未知协议”错误(或类似错误)。如果在转换为字符串类型后仍出现此错误,请尝试使用 StringIO
而不是 :
import requests
from io import StringIO
...
data = pandas.read_json(StringIO(response.text))
其中 response
是 requests
库中对象 Response
的实例,其属性 text
包含 json 文本数据。
我在使用 pyodbc
将参数传递到 SQL INSERT 语句时遇到了同样的错误。正如罗伯特所提到的,只需将变量转换为字符串即可。
示例: 语法 - str()
cursor.execute("INSERT INTO Table ([col1],[col2],[col3]...])VALUES(?,'test',?)", str(value1), str(value3))