2010-07-10 13 views
36

Tengo un script de Python que lee archivos de texto de película en una base de datos sqlite.Escapar caracteres en Python y sqlite

Utilizo re.escape (título) para agregar caracteres de escape en las cadenas para que sean seguros antes de ejecutar las inserciones.

¿Por qué no funciona:

In [16]: c.execute("UPDATE movies SET rating = '8.7' WHERE name='\'Allo\ \'Allo\!\"\ \(1982\)'") 
--------------------------------------------------------------------------- OperationalError      Traceback (most recent call last) 

/home/rajat/Dropbox/amdb/<ipython console> in <module>() 

OperationalError: near "Allo": syntax error 

Sin embargo, esto funciona (eliminado \' en dos lugares):

In [17]: c.execute("UPDATE movies SET rating = '8.7' WHERE name='Allo\ Allo\!\"\ \(1982\)'") Out[17]: <sqlite3.Cursor object at 0x9666e90> 

No puedo entenderlo. Tampoco puedo deshacerme de esas citas principales porque en realidad son parte del título de la película. Gracias.

Respuesta

85

Lo estás haciendo mal. Literalmente. Usted debe estar utilizando parámetros, así:

c.execute("UPDATE movies SET rating = ? WHERE name = ?", (8.7, "'Allo 'Allo! (1982)")) 

Al igual que usted no tendrá que hacer ningún citando a todos y (si esos valores son procedentes de cualquiera que no sea de confianza) podrás 100% seguro (aquí) de los ataques de inyección SQL también.

+5

absolutamente. citar y escapar son kludges de último recurso. si los parámetros están disponibles, úselos _todas_ – Javier

+2

BTW, la misma idea funciona igual para casi cualquier otra base de datos que merezca el mismo nombre, y en prácticamente cualquier otro lenguaje de programación práctico. * Todos * lo hacen de esta manera porque es * correcto *. –

+0

Gracias increíbles Donal. Todo funciona bien ahora. Utilicé métodos similares con RoR, donde está bien documentado. Pero las horas de búsqueda de "caracteres de escape python sqlite" no arrojaron nada. los documentos de Python dejan mucho que desear.Gracias Donal y todos –

8

utilizo re.escape (título) para añadir caracteres de escape en las cuerdas para hacerlas db segura

Tenga en cuenta que re.escape hace una cadena re -safe - nada que ver con lo que es db seguro. Por el contrario, como @Donal dice, lo que necesita es el parámetro sustitución concepto de la API de Python DB - que hace las cosas "db safe" como sea necesario.

4

SQLite no admite secuencias de escape de barra invertida. Los apóstrofos en literales de cadena se indican al doblarlos: '''Allo ''Allo! (1982)'.

Pero, como dijo Donal, deberías usar parámetros.

-2

Tengo un consejo sencillo que podría usar para manejar este problema: Cuando su cadena de instrucción SQL tiene comilla simple: ', entonces podría usar comillas dobles para encerrar su cadena de instrucción. Y cuando su secuencia de comandos de SQL tenga comillas dobles: ", entonces podría usar comillas simples:" para encerrar su cadena de instrucciones. P. ej.

sqlString="UPDATE movies SET rating = '8.7' WHERE name='Allo Allo !' (1982)" 
c.execute(sqlString) 

O

sqlString='UPDATE movies SET rating = "8.7" WHERE name="Allo Allo !" (1982)' 
c.execute(sqlString) 

Esta solución funciona para mí en el entorno Python.

+0

¿Y si el valor que busca tiene una comilla doble en él? Use los parámetros según la respuesta de Donal. O escape (solo como último recurso) contra el carácter delimitador (comilla simple en la pregunta OP, o comillas dobles en su ejemplo) – colminator

+0

colminator, mi cadena no tiene comillas dobles. Si su cadena tiene una comilla doble, simplemente use "\" ". –

+0

Tiene un ejemplo estático. En el mundo real, la cláusula WHERE sería dinámica. No se puede confiar en que el contenido dinámico tenga conflictos de delimitador sin escaparse, ya sea que use comillas simples o dobles. – colminator

Cuestiones relacionadas