代码之家  ›  专栏  ›  技术社区  ›  Sebastian Bartos

有没有办法使用。编译python 3 sqlite 3游标时的format()语法。executestript()语句是否安全?

  •  1
  • Sebastian Bartos  · 技术社区  · 7 年前

    我正在构建一些依赖SQLite SQL语句的Python代码 很多 (我从单独的文件中读取)使用一些Python 3粘合代码。这意味着我有多页SQL模板,我在Python中提供参数,现在我想知道应该如何转义变量。

    官方方式是: c.execute("INSERT INTO foo VALUES (?, ?, ?)", (a, b, c)) ,这对于小的SQL片段来说很可爱,但对于多页SQL语句来说有点不切实际(第35个问号又在哪里?)。

    类似于 .format() 函数语法会更有用,例如: c.executescript("... INSERT INTO foo VALUES ({a}, {b}, {c}); ...".format(a='a', b='b', c="Robert'); DROP TABLE foo; --", ...)

    实际的SQL模板字符串将从文件中读取,并作为变量放置,因此 c.executescript(fp.read().format(a='a', b='b', c="Robert'); DROP TABLE foo; --", ...) . 最终结果是 params={'a':'a', 'b':'b', 'c': "Robert'); DROP TABLE foo; --"}, c.executemany(fp.read().format(**params))

    这可能吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   CL.    7 年前

    SQLite支持 named parameters :

    c.execute("SELECT :a, :b", {'a': 1, 'b': 'hello'})
    

    但是,参数仅适用于单个SQL语句。对于 executescript() ,必须直接插入值,并且必须正确转义SQL字符串:

    def sql_string(s):
        return "'" + s.replace("'", "''") + "'"
    
    c.executescript(template.format(a=sql_string('Bob...')))