Använd en parametriserad fråga enligt beskrivningen i dokumenten
Eftersom du redan har ett diktat kan du göra:
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)
Jag har inte testat om if fungerar med ett beställt dikt, men jag tycker att det borde. Om inte, kan du göra ditt beställda dikt till ett vanligt dikt innan du skickar det som parametermappning.
REDIGERA Om du inte behöver dina parametrar för att vara ett OrderedDict senare, använd ett vanligt dict. Såvitt jag kan se valde du bara en OrderedDict för att bevara värdeordningen för list(query_params.values())[0]
.
EDIT2 Tabellnamn och fältnamn kan inte skickas med bindningar. Antoine Dusséaux påpekade i det här svaret att psycopg2 erbjuder ett mer eller mindre säkert sätt att göra det sedan version 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)
Du kanske måste ta bort table_name
från din dict är jag inte säker på hur psycopg2 reagerar på ytterligare objekt i parametrarna dict och jag kan inte testa det just nu.
Det bör påpekas att detta fortfarande utgör en risk för SQL-injektion och bör undvikas om det inte är absolut nödvändigt. Normalt är tabell- och fältnamn en ganska fast del av en frågesträng.
Här är den relevanta dokumentationen för sql
modul
.