Harap gunakan kueri berparameter seperti yang dijelaskan dalam dokumen
Karena Anda sudah memiliki dict, Anda dapat melakukan:
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)
Saya belum menguji apakah jika berfungsi dengan dict odered, tapi saya pikir itu harus. Jika tidak, Anda dapat membuat dict yang dipesan menjadi dict biasa sebelum meneruskannya sebagai pemetaan parameter.
EDIT Kecuali Anda memerlukan parameter Anda untuk menjadi OrderedDict nanti, gunakan dict biasa. Sejauh yang saya bisa lihat, Anda hanya memilih OrderedDict untuk mempertahankan urutan nilai untuk list(query_params.values())[0]
.
EDIT2 Nama tabel dan nama bidang tidak dapat diteruskan menggunakan binding. Antoine Dusséaux menunjukkan dalam jawaban ini bahwa psycopg2 menawarkan cara yang kurang lebih aman untuk melakukannya sejak versi 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)
Anda mungkin harus menghapus table_name
dari dict Anda, saya tidak yakin bagaimana psycopg2 bereaksi pada item tambahan dalam parameter dict dan saya tidak dapat mengujinya sekarang.
Harus ditunjukkan, bahwa ini masih menimbulkan risiko injeksi SQL dan harus dihindari kecuali benar-benar diperlukan. Biasanya, nama tabel dan bidang adalah bagian yang agak tetap dari string kueri.
Berikut dokumentasi untuk sql
yang relevan modul
.