2015-02-27 3 views
3

У меня есть сложный sql-запрос, который мне нужно выполнить на Django и Raw SQL, кажется единственным вариантом. Мои параметры являются строками и могут быть пустыми. Причиной быть пустым является то, что у меня есть условные операторы выше, и в зависимости от того, что должен быть выполнен правильный sql. Но когда ra sql запускается, django фактически ставит кавычки (которые я использую для обозначения строк) в sql, и поэтому он выдает ошибку.Правильный способ передачи параметров, содержащих строку, в Django Raw sql

Я упростил запрос, чтобы показать проблему, с которой я столкнулся. Следующий запрос при выполнении вызывает ошибку.

select_cond = '' 
where_cond = 'id = 109' 

qraw = Book.objects.raw(
     "\ 
     SELECT id %s\ 
     FROM book\ 
     WHERE %s\ 
     ", 
     [select_cond, where_cond] 
) 

Ошибка связана с тем, что она переводится следующим образом. Кавычки действительно попадают в sql и поэтому не выполняются. Любая идея о том, как я могу это исправить?

SELECT id '' 
FROM book 
WHERE 'id = 109' 
ORDER BY id DESC; 

ответ

2

Это поведение по умолчанию для базового драйвера базы данных, используемого Django.

Примечание: Я не уверен, что мотивация пытается построить запрос таким образом.

Только если вы доверяете источнику условий где вы используете в запросах, поместите их в запрос с помощью строки форматирования:

qraw = Book.objects.raw(""" 
    SELECT 
     id, {select} 
    FROM 
     book 
    WHERE 
     {where} 
    """.format(select=select_cond, where=where_cond) 
) 

Опять же, это не безопасно, так как вы что делает его уязвимым для инъекций SQL.


Чтобы сделать его более безопасным вы можете предварительно разобрать, где условия вы будете использовать в запросе и вызвать MySQLdb.escape_string() вручную значений поля, например:

key, value = where_cond.split(' = ') 
value = MySQLdb.escape_string(value) 
where_cond = ' = '.join(key, value) 
+0

Я предполагаю, что это не безопасно 3 раза недостаточно, чтобы избежать опускания. – alecxe

2

Django предоставляет 'params' argument для raw, что позволяет избежать атаки SQL-инъекций. Как показывает пример @ alecxe, тройные кавычки в python - отличный способ определить многострочную переменную и избежать любых проходов линии обратной косой черты. Вот предлагаемое безопасное решение «Джанго путь»:

select_cond = condition 
where_cond = condition 

qraw = Book.objects.raw(""" 
    SELECT 
     id, %(select_cond)s 
    FROM 
     book 
    WHERE 
     %(where_cond)s 
    """, params={'select_cond': select_cond, 'where_cond': where_cond}) 

Просто замените условию заполнителей с соответствующими значениями.

Смежные вопросы