将包含字符串的参数传递到Django Raw sq的正确方法

2024-06-09 18:56:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有许多复杂的sql查询需要在Django上执行,而原始sql似乎是唯一的选择。我的参数是字符串,可以为空。之所以为空是因为我上面有条件语句,并且取决于需要执行正确的sql。但是,当rasql运行时,django实际上在sql中放入引号(我用引号表示字符串),因此它抛出一个错误。在

我简化了查询以显示我所面临的问题。执行以下查询时抛出错误。在

select_cond = ''
where_cond = 'id = 109'

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

错误是由于它被翻译成如下所示。引号实际上进入了sql,因此它不会执行。有什么办法解决这个问题吗?在

^{pr2}$

Tags: django字符串idsql参数错误语句where
2条回答

这是Django使用的底层数据库驱动程序的默认行为。在

注意:我不确定试图以这种方式构造查询背后的动机。在

只有当您信任查询中使用的where条件的源时,才通过字符串格式将它们放入查询中:

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

同样,这样做是不安全的,因为您实际上使它容易受到SQL注入的攻击。在


为了更安全,您可以预先分析查询中将使用的where条件,并手动调用字段值MySQLdb.escape_string(),例如:

^{pr2}$

Django为raw提供了一个'params' argument,可以避免潜在的SQL注入攻击。正如@alecxe的示例所示,python中的三引号是定义多行变量并避免任何反斜杠换行的好方法。这里有一个建议的安全解决方案“Django方式”:

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})

只需将条件占位符替换为适当的值。在

相关问题 更多 >