[Python-de] pypgsql Tabellenamen mit grossbuchstaben nicht erlaubt?

Hans-Peter Jansen hpj at urpla.net
Mit Feb 9 12:31:20 CET 2005


On Wednesday 09 February 2005 00:34, Diez B. Roggisch wrote:
> > Wenn ich nicht etwas sehr falsch verstanden habe, muß man in dem
> > Datentupel auch die in den Daten steckenden Quotes escapen, e.g.:
> >
> > c.execute(
> >     """INSERT INTO breakfast (name, spam, eggs, sausage, price)
> >     VALUES (%s, %s, %s, %s, %s)""",
> >           ('Spam and Sausage Lover\'s Plate', 5, 1, 8, 7.95 ))
> >
> > In meinem Fall baue ich den INSERT string on the fly zusammen,
> > und muß je nach verwendetem String Quote eben diesen escapen,
> > oder weißt Du was besseres?
>
> dein eigenes Beispiel ist das Gegenbeispiel. Der escape ist nur
> notwendig, weil du singlequotes verwendest. Wenn du aber
> stattdessen doublequotes genommen haettest, waers ok ohne escape.

..würde dann aber über z.B. ("Guido "Mr. Python" van Rossum", ...) 
stolpern.

> Wenn du aber den String komplett baust, dann
>  -  _musst_ du singlequotes verwenden fuer den string parameter
> selbst - das enthaltene s-quote so escapen, das es aus Sicht der DB
> escaped ist. Das kann ein slash sein, oder wie bei oracle ein
> doppeltes quote. Das ist db-spezifisch, und darum nicht
> standardisiert.
>
> Also etwa so (ungetestet):
>
> "insert into foo (some_string) values ('bar\\'baz')"

Yup, genau das meinte ich.

Hier ist mein Realworld example. orderkeys ist eine Liste mit 
Feldnamen, rec ist ein (CSV) dict mit den Daten:

        # prepare sql statement
        sqlinsert = "INSERT INTO %s (id, ordernr, " % (deliverytable)
        sqlvalues = "VALUES (NULL, %(ordernr)s, "
        for k in orderkeys:
            sqlinsert += "%s, " % k
            sqlvalues += "'%%(%s)s', " % k
        sqlinsert = sqlinsert[:-2] + ")\n"
        sqlvalues = sqlvalues[:-2] + ");"

        sqlexp = (sqlinsert + sqlvalues) % rec

 Ich sehe hier keine Möglichkeit, um's escapen herumzukommen.
Alternativ könnte ich natürlich eine Liste mit den Daten 
zusammenbauen, aber ich finde das immer noch recht lesbar..

> Es gibt uebrigens noch einen weiteren, sehr wichtigen Grund die
> parameter-bindende Variante zu waehlen: Zur Ausfuehrung eines
> Statements gehoert nicht nur das eigentliche parsen, sondern
> insbesondere der sog. Execution Plan. Dieser bestimmt, welche
> Tabellen mit welchen Spalten und eventuell Indizes in welcher
> Reihenfolge abgearbeitet werden. Diesen EP zu erstellen kann
> durchaus aufwendig weil nichttrivial sein. Wenn man jetzt die
> gebundene Variante nutzt, sehen hundert statements trotz
> verschiedener daten aus Sicht der DB immer gleich aus - mit anderen
> Worten, man kann den EP cachen. Und das ist der Performance seeeehr
> zutraeglich.

Hmm, daran habe ich noch nicht gedacht, in obigen Fall sind es so 
10-50 Records am _Tag_, also ist die Insert Performance nicht so 
entscheidend ;-)

> Obiges gilt speziell fuer Oracle, aber ich denke mal auch andere
> optimierende DBs haben aehnliches Mechanismen.
>
> Natuerlich ist eine weitere Vorraussetzung, das der Treiber die
> entsprechenden calls macht, und nicht intern das oben angedeutete
> escaping macht - bei oracle ist das zb die Verwendung von ocibind.

Huch, hängt bei solchen quote Problemen nicht der Interpreter 
dazwischen, und der DB-Treiber wird wohl kaum versuchen, die Strings 
wieder anders zusammen zu setzen, oder?

Pete