Необработанные запросы Django и переменная, объявляемая Postgres

У меня есть файл с множеством необработанных sql-запросов, в котором используется подстановка текста, т.е.

select * from table1 where date_col between '%%from_date%%' and '%%to_date%%'

затем эти %%date_from%% и %%date_to%% заменяются значениями с помощью функции python string replace. Это работает нормально, и запросы работают. Однако это не является бездействием, так как может быть открыто для sql-инъекций. (и нет, я не могу использовать модели или что-то еще, кроме необработанного sql), что еще хуже, я не могу использовать %s и параметризировать запросы, потому что переменные меняют порядок, а %s работает по порядку (насколько я могу судить)

Я думал об использовании declare, чтобы иметь мои переменные в начале блока select, т.е.

sql - 
declare from_date date:= %s
declare to_date date:= %s
select * from table1 where date_col between to_date and from_date

python - 
with with connection.cursor() as cursor:
  cursor.execute(query, [from_date, to_date'])

но это выдает

django.db.utils.ProgrammingError: syntax error at or near "date"
LINE 1: DECLARE from_date date := '2022-01-01'::date DECLARE to_date...
                          ^

Я не знаю, что я делаю неправильно и буду рад любой помощи. насколько я могу судить, я правильно понял синтаксис, возможно django raw queries поддерживает только select? есть ли другой способ заставить его работать с параметризацией? буду признателен за помощь

Попробуйте сделать верхний CTE для хранения ваших переменных, вместо этого:

with invars as (
  select (%s)::date as from_date, (%s)::date as to_date
)
select *
  from invars i
       join table1 t 
         on t.date_col between i.to_date and i.from_date;

Если проблема в том, что иногда from_date и to_date путаются, то можно использовать BETWEEN SYMMETRIC.

Если вам нужно использовать эти переменные в запросе или другом CTE, который не имеет ничего для присоединения к invars, то используйте cross join, чтобы сделать столбцы invar доступными.

Вернуться на верх