Intento insertar un montón de datos en la base de datos.
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: ('Tipo de parámetro no válido. param-index=4 param-type=numpy.int64', 'HY105')
reducir a 100 tuplas:
cursor.executemany(sql, insert_list[:100])cursor.executemany(sql, insert_list[:100])
pyodbc.ProgrammingError: ('Tipo de parámetro no válido. param-index=4 param-type=numpy.int64', 'HY105') cursor.executemany(sql, insert_list[:100])
reducir a 5 tuplas:
cursor.executemany(sql, insert_list[:5]) conn.commit()Esto puede insertar en la base de datos
He intentado:
sql = 'SET GLOBAL max_allowed_packet=50*1024*1024' cursor.execute(sql)antes de excutemany() pero tiene un error:
pyodbc.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]'GLOBAL' no es una opción SET reconocida. (195) (SQLExecDirectW)")
¿Cómo resolví esto?
Gracias.
Su problema no es el volumen de datos per se , es que algunas de sus tuplas contienen valores numpy.int64 que no se pueden usar directamente como valores de parámetro para su declaración SQL. Por ejemplo,
a = numpy.array([10, 11, 12], dtype=numpy.int64) params = (1, 1, a[1], 1, 1, 1) crsr.execute(sql, params)tirará
ProgrammingError: ('Tipo de parámetro no válido. param-index=2 param-type=numpy.int64', 'HY105')
porque el valor del tercer parámetro es un elemento numpy.int64 de su matriz numpy a . Convertir ese valor con int() evitará el problema:
a = numpy.array([10, 11, 12], dtype=numpy.int64) params = (1, 1, int(a[1]), 1, 1, 1) crsr.execute(sql, params)Por cierto, la razón por la que
sql = 'SET GLOBAL max_allowed_packet=50*1024*1024' cursor.execute(sql) no funcionó es que max_allowed_packet es una configuración de MySQL que no tiene ningún significado para Microsoft SQL Server.
Hice lo mismo que Robert; Convertí todo a cadena. En mi caso, fue un marco de datos de pandas que lancé al tipo de cadena:
data = pandas.read_json(...) data.astype(str).to_sql(...)https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.astype.html
Si los datos que está recuperando incluyen direcciones URL, es posible que obtenga un error de "protocolo desconocido" (o algo así). Si obtiene este error incluso después de convertir al tipo de cadena, intente usar StringIO en su lugar :
import requests from io import StringIO ... data = pandas.read_json(StringIO(response.text)) donde response es una instancia del objeto Response de la biblioteca de requests y su text de atributo contiene los datos de texto json.
Para cualquiera que esté leyendo esto, me estaba volviendo loco.
Mi solución final fue convertir todas las variables a 'str' y funcionó bien.