我有一堆复杂的SQL查询,我需要在Django上执行,而Raw SQL似乎是唯一的选择。我的参数是字符串,可以为空。空的原因是我上面有条件语句,并且根据需要执行正确的sql。但是当运行ra sql时,django实际上在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;
答案 0 :(得分:2)
这是Django使用的基础数据库驱动程序的默认行为。
注意:我不确定尝试以这种方式构建查询的动机。
只有当您信任查询中使用的where条件的来源时,才能通过字符串格式将它们放入查询中:
qraw = Book.objects.raw("""
SELECT
id, {select}
FROM
book
WHERE
{where}
""".format(select=select_cond, where=where_cond)
)
同样,这样做并不安全,因为实际上它很容易受到SQL注入的攻击。</ p>
为了更安全,您可以预先解析您在查询中使用的条件,并在字段值上手动调用MySQLdb.escape_string()
,例如:
key, value = where_cond.split(' = ')
value = MySQLdb.escape_string(value)
where_cond = ' = '.join(key, value)
答案 1 :(得分:2)
Django为raw提供了'params' argument,避免了SQL注入攻击的可能性。正如@ alecxe的例子所示,python中的三引号是定义多行变量并避免任何反斜杠行转义的好方法。这是一个建议的安全解决方案“Django方式”:
any
只需用适当的值替换 condition 占位符。