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

Posted

技术标签:

【中文标题】Python MySQLdb/mysqlclient:绑定命名集(或元组或列表)作为参数【英文标题】:Python MySQLdb/mysqlclient: bind a named set (or tuple or list) as parameter 【发布时间】:2015-10-11 23:17:40 【问题描述】:

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

也许我找错地方了,但是关于 Python 的 mysqldb 连接器系列的文档并不多。也许PEP249 是为了完成这项工作。 Oracle 的 MySQL/Python 连接器似乎有更好的docs,但目前我正在使用mysqlclient(MySQLdb 的 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?

现在我想使用集合、列表或元组来构建带有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】:

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

查看了 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 准备了一个字节字符串,但使用绑定参数someid 构建的query 是一个字符串。也许有更简单的方法。如果你找到了,请告诉我。

【讨论】:

【参考方案2】:

我不知道如何在 MySQLdb 中具体表达它,但它可以与this other answer 中建议的 MySQL 连接器库(版本:1.4.4,MySQL 5.7.x)一起开箱即用:

cursor.execute('SELECT * FROM test WHERE id in %(l)s', 'l': (1,2,3))

如果 MySQLdb 搞砸了,那么我建议以某种方式获取直接光标。

【讨论】:

以上是关于Python MySQLdb/mysqlclient:绑定命名集(或元组或列表)作为参数的主要内容,如果未能解决你的问题,请参考以下文章

Python代写,Python作业代写,代写Python,代做Python

Python开发

Python,python,python

Python 介绍

Python学习之认识python

python初识