Na, viel gibts da nicht zu zeigen:
Code: Alles auswählen
>>> import psycopg2
>>> conn = psycopg2.connect(*zensiert*)
>>> CREATE_DB = "CREATE DATABASE %s"
>>> db_name = 'testdatenbank'
>>> cur = conn.cursor()
>>> cur.mogrify(CREATE_DB, (db_name, )) # Methode 1
"CREATE DATABASE E'testdatenbank'"
>>> cur.execute(CREATE_DB, (db_name, ))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.ProgrammingError: syntax error at or near "E'testdatenbank'"
LINE 1: CREATE DATABASE E'testdatenbank'
^
>>> cur.mogrify(CREATE_DB % db_name) # Methode 2
'CREATE DATABASE testdatenbank'
>>> cur.execute(CREATE_DB % db_name)
Methode 1 macht brav String-Escape mit diesem "E'<string>'". Da meckert jedoch PostgreSQL (tut es auch, wenn ich den Befehl per Hand in psql eingebe).
Methode 2 funktioniert problemlos, aber das soll man ja "never never never" machen.
Offensichtlich dürfen Bezeichner für Datenbanken und Rollen nicht escaped werden, denn da passiert das gleiche:
Code: Alles auswählen
>>> CREATE_ROLE = "CREATE ROLE %s WITH NOSUPERUSER LOGIN PASSWORD %s"
>>> user = "ich"
>>> passwort = "geheim"
>>> cur.mogrify(CREATE_ROLE, (user, passwort)) # Methode 1
"CREATE ROLE E'ich' WITH NOSUPERUSER LOGIN PASSWORD E'geheim'"
>>> cur.execute(CREATE_ROLE, (user, passwort))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.ProgrammingError: syntax error at or near "E'ich'"
LINE 1: CREATE ROLE E'ich' WITH NOSUPERUSER LOGIN PASSWORD E'geheim'
^
>>> CREATE_ROLE = "CREATE ROLE ich WITH NOSUPERUSER LOGIN PASSWORD %s" # Methode 2
>>> cur.mogrify(CREATE_ROLE, ( passwort, ))
"CREATE ROLE ich WITH NOSUPERUSER LOGIN PASSWORD E'geheim'"
>>> cur.execute(CREATE_ROLE, ( passwort, ))
Methode 1 versagt kläglich, Methode 2 geht wieder. Man sieht, dass das Passwort sehrwohl escaped werden darf.
Ist es von den Entwicklern nicht vorgesehen, dass man z.B. Datenbanken und Rollen mit psycopg2 erstellt? Oder ist das so ein Fall wie "Oh, du bist so Fortgeschritten und machst CREATE DATABASE und so? Dann ignorier halt das Verbot aus der Doku und setze Strings direkt ein!"
Es besteht grade gar kein praktisches Problem. User und DB-Namen werden bei mir sowieso auf r'^[a-zA-Z0-9_]+' gefiltert und Passwörter werden ja escaped. Es interessiert mich nur prinzipiell, wie es gedacht ist, unter psycopg2 solche Befehle, wo Strings nicht escaped werden
dürfen, zu handhaben sind.