Bei der Übergabe eines Variablentypnamens zur Erstellung in Postgres mit psycopg2 unter Verwendung der Formatierungsoption wurde ein Fehler über die fehlerhafte Zeichenfolgenformatierung für den Namen von Objekten geworfen. Dürfen Namen nicht mit% s innerhalb der Abfrageparameter übergeben werden?
Der Code, den ich geschrieben habe, um meine Probleme zu lösen, ist unten (nur auf der Suche nach einem besseren Weg, dies zu lösen)
cursor.execute("CREATE TYPE {0} AS ENUM %s".format(name), (tuple(set([e.upper() for e in elements])),))
3 Antworten
(2) hat nichts mit PostgreSQL zu tun. Bearbeiten Sie es möglicherweise aus dieser Frage heraus und veröffentlichen Sie es in einer neuen Frage. Ich werde antworten (1).
Wie Sie vermutet haben, können Sie beispielsweise Tabellennamen nicht als Abfrageparameter übergeben.
Sie werden als Bindungsparameter auf Protokollebene gesendet, und (kritisch) muss die Abfrage als gültiges SQL mit ihnen als Platzhalter analysiert werden können. Es ist, als würden Sie eine SQL-Ebene PREPARE
ausführen und dann EXECUTE
trennen. Sie müssen sie in die SQL-Zeichenfolge formatieren, bevor Sie sie vorbereiten.
Doppelte Anführungszeichen für die Bezeichner, die Sie ersetzen, und Vorsicht vor möglichen doppelten Anführungszeichen in der Zeichenfolge, die übergeben werden und die Ihre Anführungszeichen möglicherweise vorzeitig beenden. Diese müssen verdoppelt werden. Für den Tabellennamen some"table
würden Sie beispielsweise Folgendes verwenden:
'SELECT * FROM "{0}"'.format('some""table');
SQL-Injection ist ein sehr ernstes Risiko. Sie müssen Ihr Zitat genau richtig machen. Suchen Sie im Idealfall ein clientseitiges Äquivalent der PostgreSQL quote_ident
SQL-Funktion.
Beachten Sie, dass bei Bezeichnern in doppelten Anführungszeichen zwischen Groß- und Kleinschreibung unterschieden wird. Stellen Sie sicher, dass Sie sie mit demselben Fall in der Datenbank erstellen, indem Sie sie immer in doppelten Anführungszeichen verwenden und keine Anführungszeichen in Anführungszeichen und nicht in Anführungszeichen setzen.
Ich bin auch auf dieses Problem gestoßen und habe einen kurzen Blog-Beitrag geschrieben, der die Verbindung zu einem Blog behandelt Remote-Datenbank mit Zeichenfolgenformatierung, aber dieses Problem und meine Lösung gelten für alle Situationen, in denen Sie Variablen an SQL-Befehle übergeben müssen.
So habe ich dieses Problem umgangen:
import psycopg2 as db
import sys
my_host = 'ec2-190-111-829-829.compute-1.amazonaws.com'
my_dbname = 'myDBNameGoesHere'
my_user = 'myUsernameGoesHere'
my_password = 'myPasswordGoesHere'
remote_connection_str = 'host={0} dbname={1} user={2} password={3}'.format(my_host, my_dbname, my_user, my_password)
if __name__ == '__main__':
try:
remote_connection = db.connect(remote_connection_str)
cursor = remote_connection.cursor()
cursor.execute('SELECT version()')
version = cursor.fetchone()
print "\n"
print "Successful connection to database."
print "Database information:\n", version
print "\n"
except db.DatabaseError, e:
print 'Error %s' % e
sys.exit(1)
finally:
if remote_connection:
remote_connection.close()
Sie sollten Ihre Abfragen eigentlich nie im Python-Format formatieren, sondern psycopg2 ausführen lassen. Hier ist der Weg, um es zu machen: http: // initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries dh:
cur.execute("INSERT INTO numbers VALUES (%s)", (42,))
Ab der Version 2.7 stehen über das Modul psycopg2.sql
einige erweiterte Formatierungsmöglichkeiten zur Verfügung: http : //initd.org/psycopg/docs/sql.html
Verwandte Fragen
Neue Fragen
python
Python ist eine dynamisch typisierte Mehrzweck-Programmiersprache mit mehreren Paradigmen. Es wurde entwickelt, um schnell zu lernen, zu verstehen, zu verwenden und eine saubere und einheitliche Syntax durchzusetzen. Bitte beachten Sie, dass Python 2 ab dem 01.01.2020 offiziell nicht mehr unterstützt wird. Fügen Sie für versionenspezifische Python-Fragen das Tag [python-2.7] oder [python-3.x] hinzu. Wenn Sie eine Python-Variante (z. B. Jython, PyPy) oder eine Bibliothek (z. B. Pandas und NumPy) verwenden, fügen Sie diese bitte in die Tags ein.