MySQL consultas parametrizadas

Me está costando mucho usar el módulo MySQLdb para insertar información en mi base de datos. Necesito insertar 6 variables en la tabla.

cursor.execute (""" INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation) VALUES (var1, var2, var3, var4, var5, var6) """) 

¿Puede alguien ayudarme con la syntax aquí?

Tenga cuidado con el uso de la interpolación de cadenas para consultas SQL, ya que no escapará a los parámetros de entrada correctamente y dejará su aplicación abierta a las vulnerabilidades de inyección de SQL. La diferencia puede parecer trivial, pero en realidad es enorme .

Incorrecto (con problemas de seguridad)

 c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2)) 

Correcto (con escape)

 c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2)) 

Se agrega a la confusión de que los modificadores utilizados para vincular los parámetros en una statement SQL varían entre las diferentes implementaciones de la API DB y que la biblioteca cliente mysql usa la syntax de estilo printf lugar de la más común “?” marcador (usado por ejemplo, python-sqlite ).

Tienes algunas opciones disponibles. Usted querrá sentirse cómodo con la iterpolación de cuerdas de python. ¿Cuál es un término que podría tener más éxito buscando en el futuro cuando quiera saber cosas como esta?

Mejor para consultas:

 some_dictionary_with_the_data = { 'name': 'awesome song', 'artist': 'some band', etc... } cursor.execute (""" INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation) VALUES (%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s) """, some_dictionary_with_the_data) 

Teniendo en cuenta que probablemente ya tenga todos sus datos en un objeto o diccionario, el segundo formato se adaptará mejor a usted. También apesta tener que contar las apariencias de “% s” en una cadena cuando tienes que volver y actualizar este método en un año 🙂

Los documentos enlazados dan el siguiente ejemplo:

  cursor.execute (""" UPDATE animal SET name = %s WHERE name = %s """, ("snake", "turtle")) print "Number of rows updated: %d" % cursor.rowcount 

Así que solo necesitas adaptar esto a tu propio código, ejemplo:

 cursor.execute (""" INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation) VALUES (%s, %s, %s, %s, %s, %s) """, (var1, var2, var3, var4, var5, var6)) 

(Si SongLength es numérico, es posible que necesite usar% d en lugar de% s).

En realidad, incluso si su variable (SongLength) es numérica, todavía tendrá que formatearla con% s para enlazar el parámetro correctamente. Si intentas usar% d, obtendrás un error. Aquí hay un pequeño extracto de este enlace http://mysql-python.sourceforge.net/MySQLdb.html :

Para realizar una consulta, primero necesita un cursor, y luego puede ejecutar consultas en ella:

 c=db.cursor() max_price=5 c.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price < %s""", (max_price,)) 

En este ejemplo, max_price = 5 ¿Por qué, entonces, usa% s en la cadena? Porque MySQLdb lo convertirá a un valor literal de SQL, que es la cadena '5'. Cuando termine, la consulta dirá: "... DONDE el precio <5".

Como alternativa a la respuesta elegida, y con la misma semántica segura de Marcel, aquí hay una forma compacta de usar un diccionario de Python para especificar los valores. Tiene la ventaja de ser fácil de modificar a medida que agrega o elimina columnas para insertar:

  meta_cols=('SongName','SongArtist','SongAlbum','SongGenre') insert='insert into Songs ({0}) values ({1})'. .format(','.join(meta_cols), ','.join( ['%s']*len(meta_cols) )) args = [ meta[i] for i in meta_cols ] cursor=db.cursor() cursor.execute(insert,args) db.commit() 

Donde meta es el diccionario que contiene los valores para insertar. La actualización se puede hacer de la misma manera:

  meta_cols=('SongName','SongArtist','SongAlbum','SongGenre') update='update Songs set {0} where id=%s'. .format(','.join([ '{0}=%s'.format(c) for c in meta_cols ])) args = [ meta[i] for i in meta_cols ] args.append( songid ) cursor=db.cursor() cursor.execute(update,args) db.commit() 

Aquí hay otra forma de hacerlo. Está documentado en el sitio web oficial de MySQL. https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

En el espíritu, está usando la misma mecánica de la respuesta de @Trey Stout. Sin embargo, me parece una más bonita y más legible.

 insert_stmt = ( "INSERT INTO employees (emp_no, first_name, last_name, hire_date) " "VALUES (%s, %s, %s, %s)" ) data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23)) cursor.execute(insert_stmt, data) 

Y para ilustrar mejor cualquier necesidad de variables:

NB: tenga en cuenta el escape que se está haciendo.

 employee_id = 2 first_name = "Jane" last_name = "Doe" insert_stmt = ( "INSERT INTO employees (emp_no, first_name, last_name, hire_date) " "VALUES (%s, %s, %s, %s)" ) data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23)) cursor.execute(insert_stmt, data) 

La primera solución funciona bien. Quiero añadir un pequeño detalle aquí. Asegúrese de que la variable que está intentando reemplazar / actualizar debe ser un tipo str. Mi tipo mysql es decimal pero tuve que hacer que la variable del parámetro como str para poder ejecutar la consulta.

 temp = "100" myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,)) myCursor.execute(var)