2010-01-19 8 views
13

que estoy tratando de montar la siguiente instrucción SQL utilizando DB-API de Python:cómo generar de forma segura una instrucción SQL como el uso de Python DB-API

SELECT x FROM myTable WHERE x LIKE 'BEGINNING_OF_STRING%'; 

donde BEGINNING_OF_STRING debería ser una pitón var para ser llenado con seguridad en a través de la DB-API. Intenté

beginningOfString = 'abc' 

cursor.execute('SELECT x FROM myTable WHERE x LIKE '%s%', beginningOfString) 
cursor.execute('SELECT x FROM myTable WHERE x LIKE '%s%%', beginningOfString) 

Estoy fuera de las ideas; ¿Cuál es la forma correcta de hacer esto?

Respuesta

20

Lo mejor es separar los parámetros de la sql si es posible. Luego puede dejar que el módulo db se encargue de la correcta cotización de los parámetros.

sql='SELECT x FROM myTable WHERE x LIKE %s' 
args=[beginningOfString+'%'] 
cursor.execute(sql,args) 
+0

@ ~ unutbu: gracias, eso lo clava. No me había pasado por la cabeza simplemente anexar el% a la cadena en sí * antes de * pasarlo como un arg a través de la db-api. – laramichaels

2

EDIT:

Como se señaló Brian y Thomas, el ahora mejor manera de hacer esto sería utilizar:

beginningOfString += '%' 
cursor.execute("SELECT x FROM myTable WHERE x LIKE ?", (beginningOfString,)) 

ya que el primer método deja abierto a ataques de inyección SQL .


izquierda en la historia:

Probar:

cursor.execute("SELECT x FROM myTable WHERE x LIKE '%s%%'" % beginningOfString) 
+3

-1 '" SELECCIONE x FROM myTable DONDE x ME GUSTA '% s %%' "%" doom '; drop table x; select' "' ** Oops? ** – Brian

+0

@Brian; punto muy válido! Me estaba enfocando en el error de sintaxis; No debería haber supuesto que 'comenzar' era información limpia. Gracias por la captura! –

+0

-1 eliminado. Sin embargo, todavía tienes un error de sintaxis. Use comillas dobles para su cadena y no necesitará escapar de sus comillas simples. – Brian

-1

Toma nota de Sqlite3 documentación:

Por lo general, sus operaciones SQL necesitarán utilizar valores de variables de Python. No debe ensamblar su consulta utilizando las operaciones de cadenas de Python porque hacerlo no es seguro; hace su programa vulnerable a un ataque de inyección SQL .

En su lugar, utilice el parámetro de DB-API sustitución. Poner ? como marcador de posición donde quiera usar un valor, y , luego proporcione una tupla de valores como segundo argumento para el método execute() del cursor. (Otros módulos de la base de datos pueden usar un marcador de posición diferente, como% s o:. 1) Para ejemplo:

# Never do this -- insecure! 
symbol = 'IBM' 
c.execute("... where symbol = '%s'" % symbol) 

# Do this instead 
t = (symbol,) 
c.execute('select * from stocks where symbol=?', t) 

# Larger example 
for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), 
      ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00), 
      ('2006-04-06', 'SELL', 'IBM', 500, 53.00), 
     ]: 
    c.execute('insert into stocks values (?,?,?,?,?)', t) 

Creo que quieres esto:

cursor.execute('SELECT x FROM myTable WHERE x LIKE '%?%', (beginningOfString,)) 
+0

No, eso hará lo incorrecto. –

+0

@Thomas: ¿Por qué? Aparte del hecho de que utilicé ''%?%'' En lugar de ''?%'' (No fue totalmente consistente en su consulta, que él quería), no veo ningún problema. – Brian

+5

El problema es que? se reemplaza por la versión * citada * del argumento real que pasa. Así que, por ejemplo, "'; DROP TABLE x; SELECT'" (observe las comillas dobles simples * y * allí), termina con esta obviamente mala consulta: SELECT x FROM myTable WHERE x LIKE '%'; DROP TABLE x ; SELECCIONAR '%' –

Cuestiones relacionadas