Как передать список целых чисел в качестве аргументов для сырого SQL в django, без форматирования строки [дубликат]
Я пытаюсь понять, как передать список целых чисел в качестве аргументов для сырого SQL в Django без использования метода f-string.
Я попробовал простой метод
def raw_query(self) -> str:
return """select * from table where some_id in %s"""
и вызвать с (где ids - список целых чисел, которые я уже обернул в кортеж)
tupled_ids = tuple(ids)
with connection.cursor() as cursor:
cursor.execute(self.raw_query(), [ids])
Очевидно, что при этом аргументы заключаются в одинарную кавычку, в результате чего вместо (1,2,3) получается '(1,2,3)'. Таким образом, синтаксическая ошибка.
django.db.utils.ProgrammingError: syntax error at or near "'(1,2,3)'"
Я также пробовал
def raw_query(self) -> str:
return """select * from table where some_id = any(%s)"""
также выдает аналогичную ошибку
django.db.utils.DataError: malformed array literal: "(1,2,3,4,5)"
LINE 2: ...om table where some_id = any('(1,2,3...`
Я также пробовал использовать именованные параметры
def raw_query(self) -> str:
return """select * from table where some_id in %(ids)s"""
with connection.cursor() as cursor:
cursor.execute(sql=self.raw_query(),
params={
"ids": tuple(ids)
})
По-прежнему выдает синтаксическую ошибку.
Похоже, что django продолжает оборачивать мой список кавычками. Мне кажется, что здесь должна быть очевидная ошибка, но я не могу ее понять.
Есть и другие решения, которые предлагают сгенерировать держатель и использовать f-строку для форматирования необработанного SQL-оператора, например.
def raw_query(self, ids: list[int]) -> str:
placeholder = ','.join(['%s'] * len(ids))
return f"""select * from table where some_id in ({placeholders})"""
^ Это работает
Все же мне интересно, есть ли лучшее решение, поскольку я не хочу форматировать строку в SQL-запросе.
Любая помощь будет принята с радостью.
редактирование: я использую python 3.12 и django 5.0.3
edit2: Я не могу использовать ORM, так как реальный запрос сложнее, чем этот, и мне придется объединить 2 запроса вместе и сделать аннотацию после этого, что ORM не поддерживает.
Здесь есть похожий вопрос Passing lists or tuples as arguments in django raw sql, который возможно дублирует вопрос. Однако, это не отвечает на этот вопрос, так как я привел пример, почему это не работает, и некоторые из предложенных решений требуют, чтобы вы сделали строковое форматирование. Я активно ищу ответ, который не требует форматирования строки, если это возможно.