PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Erstellen Sie eine dynamische SQL-Abfrage mit der Python-Bibliothek psycopg2 und verwenden Sie gute Tools für Konvertierungstypen

Sie versuchen, einen Tabellennamen als Parameter zu übergeben. Sie hätten dies wahrscheinlich sofort sehen können, wenn Sie sich nur das PostgreSQL-Fehlerprotokoll angesehen hätten.

Der Tabellenname, den Sie als Parameter durch psycopg2 zu übergeben versuchen, wird maskiert, wodurch eine Abfrage wie folgt erzeugt wird:

INSERT INTO E'my_table'(name, url, id, point_geom, poly_geom) VALUES (E'ST_GeomFromText(''POLYGON(( 52.146542 19.050557, 52.148430 19.045527, 52.149525 19.045831, 52.147400 19.050780, 52.147400 19.050780, 52.146542 19.050557))'',4326)');'

Das ist nicht das, was Sie beabsichtigt haben und wird nicht funktionieren; Sie können einen Tabellennamen nicht wie ein Literal maskieren. Sie müssen die normale Python-String-Interpolation verwenden, um dynamisches SQL zu erstellen, Sie können nur parametrisierte Anweisungsplatzhalter für tatsächliche Literalwerte verwenden.

params = ('POLYGON(( 52.146542 19.050557, 52.148430 19.045527, 52.149525 19.045831, 52.147400 19.050780, 52.147400 19.050780, 52.146542 19.050557))',4326)
escaped_name = name.replace('"",'""')
curs.execute('INSERT INTO "%s"(name, url, id, point_geom, poly_geom) VALUES (ST_GeomFromText(%%s,%%s));' % escaped_name, params)

Sehen Sie, wie ich den Namen direkt interpoliert habe, um die Abfragezeichenfolge zu erzeugen:

INSERT INTO my_table(name, url, id, point_geom, poly_geom) VALUES (ST_GeomFromText(%s,%s));

(%% wird in einfaches % konvertiert durch % Substitution). Dann verwende ich diese Abfrage mit der Zeichenfolge, die das POLYGON definiert und das andere Argument zu ST_GeomFromText als Abfrageparameter.

Ich habe dies nicht getestet, aber es sollte Ihnen die richtige Vorstellung vermitteln und helfen zu erklären, was falsch ist.

SEIEN SIE ÄUSSERST VORSICHTIG Wenn Sie eine solche Zeichenfolgeninterpolation durchführen, ist dies ein einfacher Weg für die SQL-Injektion. Ich habe im oben gezeigten Code sehr grobe Anführungszeichen verwendet, aber ich möchte eine geeignete Funktion zum Angeben von Bezeichnern verwenden, wenn Ihre Client-Bibliothek eine anbietet.