¿Cómo usar variables en una declaración SQL en Python?
Tengo el siguiente código Python:
cursor.execute("INSERT INTO table VALUES var1, var2, var3,")
donde var1
es un número entero var2
y var3
son cadenas.
¿Cómo puedo escribir los nombres de las variables sin que Python los incluya como parte del texto de la consulta?
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
- No escapa ni cita.
- Es propenso a sufrir ataques incontrolados de formato de cadena, por ejemplo, inyección SQL .
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 VALUES
podrí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 paramstyle
constante 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.
Muchas maneras. NO use el más obvio ( %s
con %
) 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))