使用executemany()插入行时"无效的参数类型"(numpy.int64)

YON*_*JNS 7 python sql-server numpy pyodbc freetds

我尝试将一堆数据插入数据库

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

cursor.executemany(sql,insert_list)

pyodbc.ProgrammingError:('参数类型无效.param-index = 4 param-type = numpy.int64','HY105')

减少到100元组:

cursor.executemany(sql, insert_list[:100])
Run Code Online (Sandbox Code Playgroud)

cursor.executemany(sql,insert_list [:100])

pyodbc.ProgrammingError:('参数类型无效.param-index = 4 param-type = numpy.int64','HY105')cursor.executemany(sql,insert_list [:100])

减少到5元组:

cursor.executemany(sql, insert_list[:5])
conn.commit()
Run Code Online (Sandbox Code Playgroud)

这可以插入数据库

我试着:

sql = 'SET GLOBAL max_allowed_packet=50*1024*1024'
cursor.execute(sql)
Run Code Online (Sandbox Code Playgroud)

在excutemany()之前,它有一个错误:

pyodbc.ProgrammingError:('42000',"[42000] [FreeTDS] [SQL Server]'GLOBAL'不是公认的SET选项.(195)(SQLExecDirectW)")

我是怎么解决这个问题的

谢谢.

Gor*_*son 9

您的问题不在于数据本身的数量,而是您的某些元组包含的numpy.int64值不能直接用作SQL语句的参数值.例如,

a = numpy.array([10, 11, 12], dtype=numpy.int64)
params = (1, 1, a[1], 1, 1, 1)
crsr.execute(sql, params)
Run Code Online (Sandbox Code Playgroud)

会扔

ProgrammingError:('参数类型无效.param-index = 2 param-type = numpy.int64','HY105')

因为第三个参数值是numpy.int64numpy数组中的一个元素a.转换该值int()将避免此问题:

a = numpy.array([10, 11, 12], dtype=numpy.int64)
params = (1, 1, int(a[1]), 1, 1, 1)
crsr.execute(sql, params)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,原因

sql = 'SET GLOBAL max_allowed_packet=50*1024*1024'
cursor.execute(sql)
Run Code Online (Sandbox Code Playgroud)

没有用的max_allowed_packet是MySQL设置对Microsoft SQL Server没有任何意义.


Mar*_*cos 5

我和罗伯特做了同样的事;我将所有内容都转换为字符串。就我而言,它是一个 pandas 数据框,我将其转换为字符串类型:

data = pandas.read_json(...)
data.astype(str).to_sql(...)
Run Code Online (Sandbox Code Playgroud)

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

其中是库中response对象的实例,其属性包含 json 文本数据。Responserequeststext