¿Cómo usar variables en una declaración SQL en Python?

Resuelto user111606 asked hace 15 años • 5 respuestas

Tengo el siguiente código Python:

cursor.execute("INSERT INTO table VALUES var1, var2, var3,")

donde var1es un número entero var2y var3son cadenas.

¿Cómo puedo escribir los nombres de las variables sin que Python los incluya como parte del texto de la consulta?

user111606 avatar May 24 '09 03:05 user111606
Aceptado
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

Tenga en cuenta que los parámetros se pasan como una tupla (a, b, c). Si pasa un solo parámetro, la tupla debe terminar con una coma (a,).

La API de la base de datos realiza escapes y citas de variables adecuados. Tenga cuidado de no utilizar el operador de formato de cadena ( %), porque

  1. No escapa ni cita.
  2. Es propenso a sufrir ataques incontrolados de formato de cadena, por ejemplo, inyección SQL .
Ayman Hourieh avatar May 23 '2009 20:05 Ayman Hourieh

Se permite que diferentes implementaciones de Python DB-API utilicen diferentes marcadores de posición, por lo que necesitarás averiguar cuál estás usando; podría ser (por ejemplo, con MySQLdb):

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

o (por ejemplo, con sqlite3 de la biblioteca estándar de Python):

cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))

u otros todavía (después de que VALUESpodría tener (:1, :2, :3), o "estilos con nombre" (:fee, :fie, :fo)o (%(fee)s, %(fie)s, %(fo)s)donde pasa un dict en lugar de un mapa como segundo argumento execute). Verifique la paramstyleconstante de cadena en el módulo DB API que está utilizando y busque paramstyle en http://www.python.org/dev/peps/pep-0249/ para ver cuáles son todos los estilos de paso de parámetros.

Alex Martelli avatar May 24 '2009 01:05 Alex Martelli

Muchas maneras. NO use el más obvio ( %scon %) en código real, está abierto a ataques .

Aquí copio y pego desde pydoc de sqlite3 :

... tenga cuidado con el uso de operaciones de cadena de Python para ensamblar consultas, ya que son vulnerables a ataques de inyección SQL . Por ejemplo, un atacante puede simplemente cerrar la comilla simple e inyectar OR TRUE para seleccionar todas las filas:

# Never do this -- insecure!
symbol = input()

sql = "SELECT * FROM stocks WHERE symbol = '%s'" % symbol
print(sql)

cur.execute(sql)

Más ejemplos si es necesario:

# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))
Kashyap avatar Feb 12 '2014 17:02 Kashyap