2012-02-17 47 views
25

Estoy tratando de usar un dict para hacer un SQL INSERT. La lógica sería básicamente:Usando un dict de Python para una sentencia SQL INSERT

INSERT INTO table (dict.keys()) VALUES dict.values() 

Sin embargo, estoy teniendo un tiempo difícil averiguar la sintaxis correcta/flujo para hacer esto. Esto es lo que tengo actualmente:

# data = {...} 
sorted_column_headers_list = [] 
sorted_column_values_list = [] 
for k, v in data.items(): 
    sorted_column_headers_list.append(k) 
    sorted_column_values_list.append(v) 
sorted_column_headers_string = ', '.join(sorted_column_headers_list) 
sorted_column_values_string = ', '.join(sorted_column_values_list) 

cursor.execute("""INSERT INTO title (%s) 
      VALUES (%s)""", 
      (sorted_column_headers_string, sorted_column_values_string)) 

A partir de este recibo una excepción de SQL (creo relacionado con el hecho de que comas también están incluidos en algunos de los valores que tengo). ¿Cuál sería la forma correcta de hacer lo anterior?

Respuesta

15

Desea agregar marcadores de posición de parámetros a la consulta. Esto podría proporcionarle lo que necesita:

qmarks = ', '.join('?' * len(myDict)) 
qry = "Insert Into Table (%s) Values (%s)" % (qmarks, qmarks) 
cursor.execute(qry, myDict.keys() + myDict.values()) 
+7

Para MySQL: formato '= '' .join ([ '% s'] * len (datos)) ' – David542

+0

fyi: esto no funcionó para mí, pero @furicle answer lo hizo – Tjorriemorrie

35

Creo que el comentario sobre el uso de esto con MySQL no está del todo completo. MySQLdb no hace la sustitución de parámetros en las columnas, solo los valores (IIUC) - así que tal vez más como

placeholders = ', '.join(['%s'] * len(myDict)) 
columns = ', '.join(myDict.keys()) 
sql = "INSERT INTO %s (%s) VALUES (%s)" % (table, columns, placeholders) 
cursor.execute(sql, myDict.values()) 

Usted no está consiguiendo escapar en las columnas sin embargo, así es posible que desee comprobar a primera .. ..

Ver http://mail.python.org/pipermail/tutor/2010-December/080701.html para una solución más completa

+4

La línea' cursor.execute (qry, columns, myDict.values ​​()) 'tiene un error de sintaxis. 'cursor.execute (qry, myDict.values ​​())' es la forma correcta. – Mehraban

+3

¿hay algún problema de pedido sobre dict? – zx1986

+1

¡La mejor respuesta de todas! – Aliweb

1
table='mytable'  
columns_string= '('+','.join(myDict.keys())+')'  
values_string = '('+','.join(map(str,myDict.values()))+')'  
sql = """INSERT INTO %s %s 
    VALUES %s"""%(table, columns_string,values_string) 
+0

Buena respuesta. Compre lo que necesita para escabullir una única cotización en la unión, para ser más práctico. '(\' '+' \ ', \' '. join (myDict.keys()) +' \ ')' o mejor "('" + "', '". join (myDict.keys()) + "')" – peter

-2

¿Qué hay de:

keys = str(dict.keys()) 
keys.replace('[', '(') 
keys.replace(']', ')') 
keys.replace("'",'') 

vals = str(dict.values()) 
vals.replace('[', '(') 
vals.replace(']', ')') 

cur.execute('INSERT INTO table %s VALUES %s' % (keys, vals)) 

para Python 3:

keys = str(dict.keys())[9:].replace('[', '').replace(']', '') 
vals = str(dict.values())[11:].replace('[', '').replace(']', '') 

...

5

siempre buenas respuestas aquí, pero en Python 3, debe escribir lo siguiente:

placeholder = ", ".join(["%s"] * len(dict)) 
stmt = "insert into `{table}` ({columns}) values ({values});".format(table=table_name, columns=",".join(dict.keys()), values=placeholder) 
cur.execute(stmt, list(dict.values())) 

No se olvide de convertir a dict.values() una lista porque en Python 3, dict.values() devuelve una vista, no una lista.

Además, no NO verter el dict.values() en stmt porque, al romper una cotización de una cadena de join ing, lo que provocó el error de MySQL en insertarla. Por lo tanto, siempre debe ponerlo en cur.execute() dinámicamente.

2

Probé la solución de @ furicle pero todavía ingresa todo como una cadena; si su dict es mixta, puede que esto no funcione como usted lo desea. Tuve un problema similar y esto es lo que se me ocurrió: este es solo un generador de consultas y puede usarlo (con cambios) para trabajar con cualquier base de datos de su elección. ¡Echar un vistazo!

def ins_query_maker(tablename, rowdict): 
keys = tuple(rowdict) 
dictsize = len(rowdict) 
sql = '' 
for i in range(dictsize) : 
    if(type(rowdict[keys[i]]).__name__ == 'str'): 
     sql += '\'' + str(rowdict[keys[i]]) + '\'' 
    else: 
     sql += str(rowdict[keys[i]]) 
    if(i< dictsize-1): 
     sql += ', ' 
query = "insert into " + str(tablename) + " " + str(keys) + " values (" + sql + ")" 
print(query) # for demo purposes we do this 
return(query) #in real code we do this 

Esto es tosco y todavía necesita verificaciones de cordura, etc., pero funciona según lo previsto. de un diccionario:

tab = {'idnumber': 1, 'fname': 'some', 'lname': 'dude', 'dob': '15/08/1947', 'mobile': 5550000914, 'age' : 70.4} 

de ejecutar la consulta me sale el siguiente resultado

results of query generated by the suite

Cuestiones relacionadas