Моля, използвайте параметризирана заявка, както е описано в документите
Тъй като вече имате dict, можете да направите:
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)
Не съм тествал дали if работи с odered dict, но мисля, че трябва. Ако не, можете да направите своя подреден dict обикновен dict, преди да го подадете като съпоставяне на параметри.
РЕДАКТИРАНЕ Освен ако нямате нужда вашите параметри да бъдат OrderedDict по-късно, използвайте обикновен dict. Доколкото виждам, вие сте избрали само OrderedDict, за да запазите реда на стойностите за list(query_params.values())[0]
.
РЕДАКТИРАНЕ 2 Имената на таблиците и имената на полетата не могат да се предават чрез свързвания. Антоан Дюсео посочи в този отговор че psycopg2 предлага повече или по-малко сигурен начин за това от версия 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)
Може да се наложи да премахнете table_name
от вашия dict, не съм сигурен как psycopg2 реагира на допълнителни елементи в параметрите dict и не мога да го тествам в момента.
Трябва да се отбележи, че това все още крие риск от SQL инжектиране и трябва да се избягва, освен ако не е абсолютно необходимо. Обикновено имената на таблици и полета са доста фиксирана част от низ на заявка.
Ето съответната документация за sql
модул
.