2010-07-10 7 views
36

Ich habe ein Python-Skript, das rohe Film Textdateien in eine SQLite-Datenbank liest.Escaping Zeichen in Python und SQLite

Ich benutze re.escape (Titel), um Escape-Zeichen in die Zeichenfolgen einzufügen, um sie db-sicher zu machen, bevor die Einfügungen ausgeführt werden.

Warum funktioniert das nicht:

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 

Doch funktioniert diese (entfernt \‘in zwei Plätze):

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

ich es nicht herausfinden. Ich kann auch diese führenden Zitate nicht wegwerfen, weil sie tatsächlich Teil des Filmtitels sind. Danke.

Antwort

85

Sie tun es falsch. Buchstäblich. Sie sollten mit Hilfe von Parametern werden, wie folgt aus:

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

So ist, werden Sie nicht jede unter Angabe überhaupt tun müssen, und (wenn diese Werte kommen von jemand nicht vertrauenswürdigen) Sie ist 100% ig werden (hier) auch von SQL-Injection-Angriffen.

+5

absolut. Quoting und Escaping sind Last-Resource-Kludges. Wenn Parameter verfügbar sind, benutze sie _always_ – Javier

+2

BTW, die gleiche Idee funktioniert genauso gut für so ziemlich jede andere Datenbank, die den Namen auch verdient, und in praktisch jeder anderen praktischen Programmiersprache. * Jeder * macht es so, weil es * richtig * ist. –

+0

Super danke Donal. Alles funktioniert jetzt gut. Ich hatte ähnliche Methoden mit RoR verwendet, wo es gut dokumentiert ist. Aber stundenlanges Suchen nach "python sqlite escape characters" brachte nichts. Python-Dokumente lassen viel zu wünschen übrig.Danke Donal und alle –

8

Ich benutze re.escape (Titel) Flucht Zeichen in die Saiten fügen Sie db sicher

Hinweis zu machen, dass re.escape einen String macht re -safe - nichts zu tun mit der Herstellung db sicher. Eher, wie @Donal sagt, was Sie brauchen, ist die Parameterersetzung Konzept der Python DB API - , die Dinge "db sicher" macht, wie Sie brauchen.

4

SQLite unterstützt Backslash-Escape-Sequenzen nicht. Apostrophe in Zeichenfolgenliteralen werden angezeigt, indem sie verdoppelt werden: '''Allo ''Allo! (1982)'.

Aber wie Donal sagte, sollten Sie Parameter verwenden.

-2

Ich habe einen einfachen Tipp, den Sie verwenden könnten, um dieses Problem zu behandeln: Wenn Ihre SQL-Anführungszeichenfolge ein einzelnes Anführungszeichen hat: ', dann könnten Sie doppelte Anführungszeichen verwenden. Und wenn Ihre SQL-Anweisungsfolge doppelte Anführungszeichen hat: ", dann könnten Sie single quote:" verwenden, um Ihre Anweisungszeichenfolge einzufügen. Zum Beispiel

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

Oder

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

Diese Lösung funktioniert für mich in Python-Umgebung.

+0

Und was passiert, wenn der Wert, den Sie suchen, ein Doppelzitat enthält? Verwenden Sie Parameter gemäß Donals Antwort. Oder flüchten Sie (nur als letzten Ausweg) gegen das Begrenzungszeichen (einfaches Anführungszeichen in der OP-Frage oder doppelte Anführungszeichen in Ihrem Beispiel) – colminator

+0

colminator, meine Zeichenfolge hat kein double-quote. Wenn Ihre Zeichenfolge double-quote hat, verwenden Sie einfach "\" ". –

+0

Sie haben ein statisches Beispiel. In der realen Welt - die WHERE-Klausel wäre dynamisch. Dynamischer Inhalt kann nicht vertraut werden Delimiter Konflikte ohne zu entkommen - ob Sie verwenden einzelne oder doppelte Anführungszeichen. – colminator