Python MySQLdb / mysqlclient:将命名集(或元组或列表)绑定为参数

时间:2015-07-22 07:52:53

标签: python mysql python-3.x mysql-python named-parameters

背景:关于MySQLdb连接器的文档不多

也许我正在寻找错误的地方,但是关于Python MySQLdb系列连接器的文档并不多。也许PEP249意味着要完成这项工作。 Oracle的MySQL / Python连接器似乎有更好的docs,但目前我正在使用mysqlclient(MySQL的3.x版本,包含C语言)连接器)。

MySQLdb中的命名参数:适用于单个值

经过多次搜索,我偶然发现了绑定命名参数的漂亮语法,只要它们是单个值即可。例如(简化案例的简化查询):

query = """
        SELECT... 
        WHERE 
             name = %(name)s AND
             gender = %(gender)s
        """
parameters = {'name': name, 'gender': gender}
cursor.execute(query, parameters)

这正确地逃避了参数。了不起。

MySQLdb中的命名参数:如何使用iterables?

现在我想使用set,list或tuple来构建IN的查询。类似的东西:

query = """
        SELECT... 
        WHERE 
        gender = %(gender)s AND
        name IN %(nameset)s
        """

我发现了类似的问题here,但该查询并未使用命名参数(占位符已命名,但不是可迭代的)。

我错过了什么?有人会知道这个有用的神奇语法吗?

我在MySQLdb代码中看到paramstyle设置为format而不是pyformat,但pyformat适用于单个值。

澄清,

  • 我对一个只构建类似('sophie', 'jane', 'chloe')的字符串并将其连接到查询的答案不感兴趣。我需要绑定参数来保证正确的转义。
  • 我对连接使用db.escape_string()的连接也不感兴趣,尽管如果没有别的方法可行,我可能最终会走这条路。

我真正追求的是一个干净的习惯用法,它绑定了名为可迭代的参数(如果有的话)。

1 个答案:

答案 0 :(得分:-1)

不要回答我自己的问题,但这已经过了一天......

查看了MySQLdb代码,看起来我没有实现我的愿望。引用函数总是会添加一组引号太多。

这就是我结束的地方(我提到的后备选项):

idset = ('Chloe', 'Zoe', "Noe';drip dautobus")

quoted_ids = [mdb.escape_string(identifier).decode('utf-8') for identifier in idset]
sql_idset = "('" + "', '".join(quoted_ids) + "')"

query = """
        SELECT ...
            FROM ...
            JOIN ...
            WHERE
              someid = %(someid)s AND
              namae IN """ + sql_idset

parameters = {'someid': someid}
cursor.execute(query, parameters)

只绑定了其中一个参数。 IN子句中的集合已预先引用。 不是我最喜欢的事情,但至少每个值都通过MySQLdb引用函数运行,以引用任何可能有害的东西。

decode因为escape_string准备了一个字节字符串,但使用绑定参数query构建的someid是一个字符串。也许有一种更简单的方法。如果你找到一个,请告诉我。