2010-07-10 11 views
36

J'ai un script python qui lit les fichiers texte brut dans une base de données sqlite.Échapper des caractères dans Python et sqlite

J'utilise re.escape (titre) pour ajouter des caractères d'échappement dans les chaînes pour les sécuriser avant d'exécuter les insertions.

Pourquoi ça marche pas:

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 

Pourtant, cela fonctionne (enlevé \ » en deux endroits):

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

Je ne peux pas comprendre. Je ne peux pas non plus laisser tomber ces citations principales parce qu'elles font réellement partie du titre de film. Merci.

Répondre

85

Vous le faites mal. Littéralement. Vous devez utiliser les paramètres, comme ceci:

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

Comme ça, vous ne devez faire aucune du tout et citaient (si ces valeurs viennent de toute personne non fiable), vous serez 100% sûr (ici) des attaques par injection SQL aussi.

+5

absolument. les citations et les échappements sont des kludges de dernière ressource. si les paramètres sont disponibles, utilisez-les _always_ – Javier

+2

BTW, la même idée fonctionne aussi bien pour presque toutes les autres bases de données valant le nom là-bas aussi, et dans pratiquement tous les autres langages de programmation pratique. * Tout le monde * le fait de cette façon parce que c'est * juste *. –

+0

Génial, merci Donal. Tout fonctionne bien maintenant. J'avais utilisé des méthodes similaires avec RoR, où il est bien documenté. Mais les heures de recherche de "caractères d'échappement python sqlite" n'ont rien donné. Les docs python laissent beaucoup à désirer.Merci Donal et tout –

8

J'utilise re.escape (titre) pour ajouter échapper dans les cordes caractères pour les rendre db sécurité

Notez que re.escape fait une chaîne re -safe - rien à voir avec le faire db sûr. Plutôt, comme le dit @Donal, ce que vous avez besoin est le remplacement de paramètre concept concept de l'API DB Python - que rend les choses "db safe" comme vous avez besoin. SQLite ne prend pas en charge les séquences d'échappement de type barre oblique inverse (

)
4

Les apostrophes dans les chaînes littérales sont indiquées en les doublant: . Mais, comme l'a dit Donal, vous devriez utiliser des paramètres.

-2

J'ai une astuce simple que vous pouvez utiliser pour gérer ce problème: Lorsque votre chaîne d'instruction SQL a guillemets simples: ', vous pouvez utiliser un guillemet double pour entourer votre chaîne d'instruction. Et quand votre chaîne d'instruction SQL a des guillemets doubles: ", alors vous pourriez employer la citation simple:" pour enfermer votre chaîne d'instruction. E.g.

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

Ou,

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

Cette solution fonctionne pour moi dans l'environnement Python.

+0

Et si la valeur que vous recherchez contient une double-citation? Utilisez les paramètres selon la réponse de Donal. Ou échapper (seulement en dernier recours) contre le caractère de délimitation (guillemets simples dans la question OP, ou guillemets dans votre exemple) – colminator

+0

colminator, ma chaîne n'a pas de guillemet double. Si votre chaîne a une double citation, utilisez simplement "\" ". –

+0

Vous avez un exemple statique Dans le monde réel - la clause WHERE serait dynamique On ne peut pas faire confiance au contenu dynamique pour avoir des conflits de délimiteurs sans s'échapper - que vous utilisiez guillemets simples ou doubles. – colminator

Questions connexes