PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Utilizzo di un dizionario per passare parametri all'istruzione postgresql in python

Utilizzare una query parametrizzata come descritto in i documenti

Dato che hai già un dict, potresti fare:

sql_data_sample = """select * from %(table_name)s
           where dt = %(date_from)s
           and target in ('ACTIVE')
           ----------------------------------------------------
           union all
           ----------------------------------------------------
           (select * from %(table_name)s
           where dt = %(date_to)s
           and target in (%(class_target)s));"""

cur.execute(sql_data_sample, query_params)

Non ho testato se funziona con un dict ordinato, ma penso che dovrebbe. In caso contrario, potresti rendere il tuo dict ordinato un dict normale prima di passarlo come mappatura dei parametri.

MODIFICA A meno che tu non abbia bisogno che i tuoi parametri siano un OrderedDict in seguito, usa un normale dict. Per quanto posso vedere, hai optato per un OrderedDict solo per preservare l'ordine dei valori per list(query_params.values())[0] .

EDIT2 I nomi delle tabelle ei nomi dei campi non possono essere passati utilizzando le associazioni. Antoine Dusséaux ha sottolineato in questa risposta che psycopg2 offre un modo più o meno sicuro per farlo dalla versione 2.7.

from psycopg2 import sql

sql_data_sample = """select * from {0}
           where dt = %(date_from)s
           and target in ('ACTIVE')
           ----------------------------------------------------
           union all
           ----------------------------------------------------
           (select * from {0}
           where dt = %(date_to)s
           and target in (%(class_target)s));"""

cur.execute(sql.SQL(sql_data_sample)
                .format(sql.Identifier(query_params['table_name'])), 
            query_params)

Potrebbe essere necessario rimuovere il table_name dal tuo dict, non sono sicuro di come psycopg2 reagisca su elementi aggiuntivi nei parametri dict e non posso testarlo in questo momento.

Va sottolineato che ciò rappresenta ancora il rischio di SQL injection e dovrebbe essere evitato a meno che non sia assolutamente necessario. Normalmente, i nomi di tabelle e campi sono una parte piuttosto fissa di una stringa di query.

Ecco la documentazione per sql modulo .