【问题标题】:Escaping chars in Python and sqlite在 Python 和 sqlite 中转义字符
【发布时间】:2011-03-14 07:07:13
【问题描述】:

我有一个 python 脚本,可以将原始电影文本文件读入 sqlite 数据库。

我使用 re.escape(title) 将转义字符添加到字符串中,以使它们在执行插入之前安全。

为什么这不起作用:

In [16]: c.execute("UPDATE movies SET rating = '8.7' WHERE name='\'Allo\ \'Allo\!\"\ \(1982\)'")
--------------------------------------------------------------------------- OperationalError                       Traceback (most recent call last)

/home/rajat/Dropbox/amdb/<ipython console> in <module>()

OperationalError: near "Allo": syntax error

但是这有效(在两个地方删除了 \'):

In [17]: c.execute("UPDATE movies SET rating = '8.7' WHERE name='Allo\ Allo\!\"\ \(1982\)'") Out[17]: <sqlite3.Cursor object at 0x9666e90>

我想不通。我也不能放弃那些主要的引语,因为它们实际上是电影标题的一部分。 谢谢。

【问题讨论】:

    标签: python sqlite


    【解决方案1】:

    你做错了。字面上地。您应该使用参数,如下所示:

    c.execute("UPDATE movies SET rating = ? WHERE name = ?", (8.7, "'Allo 'Allo! (1982)"))
    

    这样,您根本不需要进行任何引用,并且(如果这些值来自不受信任的任何人)您也将 100% 安全地(此处)免受 SQL 注入攻击.

    【讨论】:

    • 绝对。引用和转义是最后的资源组合。如果参数可用,请始终使用它们
    • 顺便说一句,同样的想法也适用于几乎所有其他名副其实的数据库,以及几乎所有其他实用的编程语言。 每个人都这样做是因为它是正确的
    • 非常感谢多纳尔。现在一切正常。我曾对 RoR 使用过类似的方法,其中有据可查。但是数小时搜索“python sqlite 转义字符”一无所获。 python 文档有很多不足之处。谢谢多纳尔和所有人
    • 请注意,这些参数仅适用于值。例如,它们不适用于列名。引用可能是一个杂项,但有时它仍然是必要的。
    • 如果您的数据库接口将用户提供的名称作为表或列标识符传递,这通常表明存在严重错误。 (或者你正在制作一个真正的专家界面,在这种情况下,你所做的不是普通的数据库代码!)
    【解决方案2】:

    我使用 re.escape(title) 添加转义 将字符转换为字符串以使它们成为 db 安全

    请注意,re.escape 使字符串 re-安全 -- 与使其 db 安全无关。相反,正如@Donal 所说,您需要的是 Python DB API 的 参数替换 概念 -- 可以根据您的需要使事情“数据库安全”。

    【讨论】:

      【解决方案3】:

      SQLite 不支持反斜杠转义序列。字符串文字中的撇号通过将它们加倍来表示:'''Allo ''Allo! (1982)'

      但是,正如多纳尔所说,您应该使用参数。

      【讨论】:

        【解决方案4】:

        我有一个简单的技巧可以用来解决这个问题: 如果您的 SQL 语句字符串有单引号:',那么您可以使用双引号将您的语句字符串括起来。当您的 SQL 语句字符串有双引号时:",那么您可以使用单引号:" 将您的语句字符串括起来。 例如

        sqlString="UPDATE movies SET rating = '8.7' WHERE name='Allo Allo !' (1982 )"
        c.execute(sqlString)
        

        或者,

        sqlString='UPDATE movies SET rating = "8.7" WHERE name="Allo Allo !" (1982 )'
        c.execute(sqlString)
        

        此解决方案适用于 Python 环境。

        【讨论】:

        • 如果您要搜索的值中有双引号怎么办?根据 Donal 的回答使用参数。或转义(仅作为最后手段)对定界字符(OP 问题中的单引号;或您的示例中的双引号)
        • colminator,我的字符串没有双引号。如果您的字符串有双引号,只需使用 "\""。
        • 您有一个静态示例。在现实世界中 - WHERE 子句将是动态的。如果没有转义,则不能相信动态内容存在分隔符冲突 - 无论您使用单引号还是双引号。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-31
        • 2011-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-03
        • 1970-01-01
        相关资源
        最近更新 更多