PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

construire une requête dynamique SQL avec la bibliothèque python psycopg2 et en utilisant de bons outils de type de conversion

Vous essayez de passer un nom de table en paramètre. Vous auriez probablement pu voir cela immédiatement si vous aviez juste regardé le journal des erreurs de PostgreSQL.

Le nom de la table que vous essayez de passer via psycopg2 en tant que paramètre est échappé, produisant une requête comme :

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)');'

Ce n'est pas ce que vous vouliez et ne fonctionnera pas ; vous ne pouvez pas échapper à un nom de table comme un littéral. Vous devez utiliser l'interpolation de chaîne Python normale pour construire du SQL dynamique, vous ne pouvez utiliser que des espaces réservés d'instruction paramétrés pour les valeurs littérales réelles.

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)

Voyez comment j'ai interpolé le nom directement pour produire la chaîne de requête :

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

(%% est converti en simple % par % de substitution). Ensuite, j'utilise cette requête avec la chaîne définissant le POLYGON et l'autre argument de ST_GeomFromText comme paramètres de requête.

Je n'ai pas testé cela, mais cela devrait vous donner la bonne idée et aider à expliquer ce qui ne va pas.

SOYEZ EXTRÊMEMENT PRUDENT lors d'une interpolation de chaîne comme celle-ci, c'est une voie facile pour l'injection SQL. J'ai fait des citations très grossières dans le code ci-dessus, mais je voudrais utiliser une fonction de citation d'identifiant appropriée si votre bibliothèque cliente en propose une.