Użyj zapytania parametrycznego zgodnie z opisem w dokumentacji
Ponieważ masz już dyktowanie, możesz zrobić:
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)
Nie testowałem, czy działa z odredem, ale myślę, że powinno. Jeśli nie, możesz sprawić, że zamówiony dykt będzie zwykłym dyktatem, zanim przekażesz go jako mapowanie parametrów.
EDYTUJ O ile nie potrzebujesz później swoich parametrów jako OrderedDict, użyj zwykłego dict. O ile widzę, wybrałeś tylko OrderedDict, aby zachować kolejność wartości dla list(query_params.values())[0]
.
EDYTUJ2 Nazwy tabel i nazw pól nie mogą być przekazywane za pomocą powiązań. Antoine Dusséaux wskazał w tej odpowiedzi że psycopg2 oferuje mniej lub bardziej bezpieczny sposób na zrobienie tego od wersji 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)
Może być konieczne usunięcie table_name
z twojego dyktatu, nie jestem pewien, jak psycopg2 reaguje na dodatkowe elementy w dykcie parametrów i nie mogę go teraz przetestować.
Należy zauważyć, że nadal stwarza to ryzyko wstrzyknięcia SQL i należy go unikać, chyba że jest to absolutnie konieczne. Zwykle nazwy tabel i pól są raczej stałą częścią ciągu zapytania.
Oto odpowiednia dokumentacja sql
moduł
.