[Python-de] Maskierung von %

Stefan Schwarzer sschwarzer at sschwarzer.net
Fr Feb 2 21:06:02 CET 2007


Hallo Paul,

On 2007-02-02 18:48, Paul Rauch wrote:
> Stefan Schwarzer schrieb:
>> dazu noch ein Hinweis: Setze den Suchbegriff als Argument
>> in cursor.execute ein. Dadurch werden Zeichen, die in SQL
>> Sonderzeichen sind (vor allem ' , bei manchen SQL-Dialekten
>> auch \), richtig maskiert.
>>
>> Also nicht
>>
>> suchtext = "Python's Prozentzeichen"
>> cursor.execute(
>>   "SELECT text FROM table WHERE text LIKE '%%%s%%'" %
>>   suchtext)  # selbst eingesetzt - unsicher
>>
>> sondern
>>
>> suchtext = "Python's Prozentzeichen"
>> cursor.execute(
>>   "SELECT text FROM table WHERE text LIKE '%%(suchtext)s%'",
>>   {'suchtext': suchtext})  # vom DB-Adapter eingesetzt - besser
>>
>> Beachte, dass hier der execute-Methode zwei Argumente übergeben
>> werden. Außerdem musst du die Prozentzeichen am Anfang und Ende
>> des Strings nicht verdoppeln (wenn der Datenbankadapter sauber
>> programmiert ist). Wie einzusetzende Zeichenketten zu formatieren
>> sind und wie das zweite Argument von cursor.execute aussehen
>> muss, hängt vom konkreten Datenbankadapter ab. Näheres in der
>> DB-API 2.0, an die sich alle neueren Adapter halten sollten,
>> http://www.python.org/dev/peps/pep-0249/ , und der Doku zum von
>> dir verwendeten Datenbankadapter.
>>
> dass verstehe ich ehrlich gesagt nicht.
> ich will doch nicht das ganze query escapen, sondern nur bestimmte
> einzelne eingaben von usern.

bei der Variante mit dem zweiten Parameter werden alle Query-
Parameter angegeben, die das SQL-Statement enthält. Dazu
gehören "normale" Daten wie Zeichenketten, Zahlen und Datums-
werte, nicht jedoch z. B. ein Tabellenname hinter FROM.
Andererseits holt man die sich ja normalerweise nicht von
einem Benutzer der Webschnittstelle. :-)

Für dein Beispiel aus dem anderen Unter-Thread sähe die SQL-
Ausführung so aus (ungetestet):

# von irgendwoher, bspw. Webschnittstelle
x = "Nutzereingabe"  # ggf. mit Sonderzeichen
y = "Bla"            # ggf. mit Sonderzeichen

cursor.execute(
  # nach dem SQL-Query steht ein Komma, kein %, d. h.
  # der Datenbankadapter übernimmt das Einsetzen der
  # Parameter - richtig maskiert
  "UPDATE db.table SET x='%(neu)s' WHERE y='%(kriterium)s' LIMIT 1",
  {'neu': x, 'kriterium': y})

Eine Bemerkung am Rande: Wenn du den LIMIT-Zusatz wirklich
brauchst, hast du eine recht ungewöhnliche Anwendung. ;-)

Viele Grüße
Stefan