Insertando múltiples objetos de diccionario en una base de datos MySQL usando python y MySQLdb

He estado luchando con esto por horas y siento ganas de llorar ahora que no puedo entender lo que está sucediendo.

Aquí está una versión simplificada de mis datos:

mydata = [ { 'id': 123, 'thing': 'ghi', 'value': 1 }, { 'id': 456, 'thing': 'xyz', 'value': 0 } ] 

Este es el código que tengo:

 import MySQLdb as mdb con = None con = mdb.connect('localhost', 'testing', 'anothervalue', 'andanother'); cur = con.cursor() sql = "INSERT INTO `tablename` ( `id`, `thing`, `value` ) VALUES ( %(id)s, %(thing)s, %(value)s )" cur.executemany( sql, ( mine for mine in mydata ) ) con.close() 

Lo que esperaba que sucediera era que se insertaran 2 filas en nombre de tabla . Lo que realmente sucede es que el script se ejecuta sin ningún error y no se insertan filas.

¿Qué estoy haciendo mal? Si hago un solo INSERT a mano, se inserta en la tabla correctamente, así que creo que no es un problema con la base de datos MySQL, sino más bien cómo estoy pasando las variables a la base de datos.

¿Una pregunta adicional que tengo es cómo puedo insertar un valor como un flotador? En el momento en que tengo la definición de valor en la tabla como TINYTEXT NOT NULL , me gustaría que esto sea FLOAT NOT NULL pero no estoy seguro de cómo manejar la subestación anterior.

No hay necesidad de usar un generador para pasar sobre mydata . Simplemente pase mydata directamente:

 cur.executemany(sql, mydata) 

El adaptador de la base de datos pasará por mydata para usted y una expresión generadora solo inserta un bucle adicional innecesario.

Si no recibe ningún mensaje de error pero tampoco hay cambios, verifique lo siguiente:

  • Asegúrate de comprometer la transacción; ejecute con.commit() después de la llamada .executemany() .

  • Comprobar mydata que mydata no está vacío.

El adaptador de base de datos manejará correctamente los valores flotantes para usted; si una columna está marcada como FLOAT NOT NULL y usted pasa un valor flotante de Python para esa columna, Things Just Work. Para eso son los parámetros de SQL, el manejo de citas de diferentes tipos de datos correctamente.

De forma predeterminada, Auto-Commit está habilitado en MYSQL. Para verificar la configuración actual en su configuración, conéctese a su instancia MYSQL y ejecute lo siguiente.

 mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec) 

Si el valor es 1, entonces está habilitado … De lo contrario no …

Para ser honesto, tu fragmento original funciona bien para mí. Así que esto podría ser principalmente un problema de auto-commit.

Intente agregar la siguiente línea justo antes de con.close() en su código original.

 con.commit() 

Aún podría probar mi fragmento de código publicado a continuación si está habilitada la confirmación automática … ¿Puede cambiar los miembros de la lista de datos del Diccionario al tipo Tuple? Si es así, por favor vea si el siguiente fragmento de código lo ayuda.

 import MySQLdb as mdb mydata = [ { 'id': 123, 'thing': 'ghi', 'value': 1 }, { 'id': 456, 'thing': 'xyz', 'value': 0 } ] mydata_modified=[ (123, 'ghi', 1 ), ( 456, 'xyz', 0 ) ] con = None con = mdb.connect('localhost', 'testing', 'anothervalue', 'andanother'); cur = con.cursor() cur.executemany( """INSERT INTO tablename ( id, thing, value ) VALUES ( %s, %s, %s )""", mydata_modified ) con.commit() con.close() 

solo un FYI para expandir en Guddu, puedes convertir tu diccionario al tipo de tupla haciendo algo como:

 mydata_modified = [] for x in mydata: mydata_modified.append(tuple(x.values()))