如何使用 MySQLdb 不转义字符串

How to not escape strings using MySQLdb

使用 pymysqlMySQLdb 替代方法),我想知道什么是对数据库或字段名称等进行字符串替换的更好方法。例如:我们想创建一个数据库,它的名字来自一个变量(dbname = "test")。

c.execute("CREATE DATABASE `test`;")

想法 1

由于添加了引号,这不起作用。

c.execute("CREATE DATABASE %s;", (dbname,))

想法 2

这很容易受到 sql 注入。

c.execute("CREATE DATABASE `{}`;".format(dbname))

有更好的主意吗?

无法参数化标识符,例如 table 或数据库名称,因此唯一可能的方法是执行一些名称安全检查,然后使用字符串连接。

根据 MySQL documentation,带引号的标识符可以包含从 U+0001U+FFFF 的任何 Unicode 字符。 NUL 字符和从 U+10000 开始的补充字符是不允许的,因此您需要在任何给定名称中检查它们并在发现任何异常时引发异常。如果名称本身包含反引号,则必须通过加倍来转义它。 (或者,如果标识符包含任何反引号,您可以选择引发异常。)

此外,标识符不能为空,尽管我正在努力查看 MySQL 文档指出这一点的位置。

因此,用于清理标识符的 suitable 函数可能如下所示(我将留给您填写详细信息):

def sanitise_identifier(name):
    # raise exception if name is empty or not a string
    # raise exception if name contains NUL chars
    # raise exception if name contains Unicode supplementary characters (U+10000 onwards)
    return name.replace("`", "``")

那么你将按如下方式使用它:

c.execute("CREATE DATABASE `{}`;".format(sanitise_identifier(dbname)))