Cómo usar executemany en pyodbc para ejecutar múltiples consultas SELECT
Sep 27 2020
Estoy usando PYODBC para consultar una base de datos SQL varias veces en función de los valores de una columna de marco de datos de pandas (que se ve a continuación como una lista de valores, ya que usé la función ToList () para convertir la columna en una lista.
#the connection string
cnxn = pyodbc.connect(driver='{SQL Server}', server = 'NameOfTheServer',autocommit = True,uid ='name',pwd ='password')
cursor = cnxn.cursor()
params = ['3122145', '523532236']
sql = ("""
SELECT SO.column
FROM table AS SO
WHERE SO.column = ?
""")
cursor.executemany(sql, params)
row = cursor.fetchone()
la función executemany arroja un error aunque estoy usando una lista: TypeError: ('Los parámetros deben estar en una lista, tupla o Fila', 'HY000')
Respuestas
GordThompson Sep 27 2020 at 23:25
.executemanyno está diseñado para utilizarse con sentencias SELECT. Si lo intentamos, solo recuperamos la última fila:
cnxn = pyodbc.connect(connection_string, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("CREATE TABLE #tmp (id int primary key, txt varchar(10))")
crsr.execute(
"INSERT INTO #tmp (id,txt) "
"VALUES (1,'one'),(2,'two'),(3,'three'),(4,'four'),(5,'five')"
)
print(crsr.execute("SELECT * FROM #tmp").fetchall())
"""console output:
[(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'five')]
"""
sql = "SELECT * FROM #tmp WHERE id = ?"
list_of_tuples = [(1,), (3,), (5,)]
crsr.executemany(sql, list_of_tuples)
print(crsr.fetchall())
"""console output:
[(5, 'five')]
"""
try:
crsr.nextset()
print(crsr.fetchall())
except pyodbc.ProgrammingError as pe:
print(pe)
"""console output:
No results. Previous SQL was not a query.
"""
En su lugar, necesitamos construir una cadena de marcadores de posición de parámetros y usarla en una cláusula IN, como esta:
tuple_of_scalars = tuple(x[0] for x in list_of_tuples)
sql = f"SELECT * FROM #tmp WHERE id IN ({','.join('?' * len(tuple_of_scalars))})"
print(sql)
"""console output:
SELECT * FROM #tmp WHERE id IN (?,?,?)
"""
crsr.execute(sql, tuple_of_scalars)
print(crsr.fetchall())
"""console output:
[(1, 'one'), (3, 'three'), (5, 'five')]
"""