2011-09-11 10 views
8

estoy tratando de cambiar el user_version de una base de datos SQLite a través de Python 2.6, y he tratado de hacer lo siguiente:No se puede usar la sustitución del parámetro sqlite3 con PRAGMA?

cur.execute("PRAGMA user_version = ?" , (version,)) 

Se produce un error con el siguiente error:

cur.execute("PRAGMA user_version = ?" , (version,)) 
sqlite3.OperationalError: near "?": syntax error 

I Probé el estilo de sustitución nombrado (en lugar de signos de interrogación) pero también falla con el mismo error.

Si incluyo un número como parte de la cadena de SQL o usando las operaciones de cadena de Python, todo funciona bien, pero prefiero no hacer ninguna de esas.

¿Por qué no funciona?
¿Y cómo inserto con seguridad un número de una variable en esta llamada?

Respuesta

4

Solo ciertos valores se pueden parametrizar. Incluso los nombres de tabla y columna no se pueden parametrizar. Su experimento muestra que los valores de pragma tampoco se pueden parametrizar.

El user_version es expected to be an integer. Puede utilizar el formato de cadenas y protegerse al mismo tiempo con

cur.execute("PRAGMA user_version = {v:d}".format(v=version)) 

El formato {v:d} elevará un ValueError si version no es un entero.

+0

Ok, pensé, ese podría ser el caso. Entonces, ¿cómo puedo insertar valores de forma segura? Si su único uso interno es el string concat o el Python% aceptable aquí? – DMA57361

+1

Esa es una buena forma de manejar la limitación cuando el parámetro es un número entero. Si el parámetro para otro pragma fuera una cadena en su lugar, no habría ninguna necesidad de verificar el formato (por ejemplo, un entero como 7 es válido como "7") pero los parámetros aún deberían escaparse para evitar la inyección de SQL. ¿Hay alguna forma conveniente de hacer eso? – spaaarky21

+0

@ spaaarky21: No conozco ninguna función proporcionada por sqlite3 para hacer citas manuales. Para otros pragmas que acepten cadenas, quizás la forma más segura sería enumerar una lista blanca de entradas admisibles y verificar la entrada del usuario en este conjunto. – unutbu

Cuestiones relacionadas