pymysql: 给 sql 语句传递字典参数
pymysql 执行 sql 操作的最主要一个方法就是:cursor.execute(sql, *args)
它给了个这样的例子:
import pymysql.cursors
# Connect to the database
connection = pymysql.connect(host='localhost',
user='user',
password='passwd',
db='db',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
# Create a new record
sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
cursor.execute(sql, ('[email protected]', 'very-secret'))
# connection is not autocommit by default. So you must commit to save
# your changes.
connection.commit()
with connection.cursor() as cursor:
# Read a single record
sql = "SELECT `id`, `password` FROM `users` WHERE `email`=%s"
cursor.execute(sql, ('[email protected]',))
result = cursor.fetchone()
print(result)
finally:
connection.close()
语句写好了,里面可能有很多占位符 %s,但是数据参数,如果有很多,又要一个一个定好位置组成 tuple 再给它么?长期这么干最后总会心累的,能不能直接传 dict 给它呢?
答案当然是可以的,有人在 stackoverflow 上也问了这个问题,答案中还解答了关于数据库驱动的 paramstyle 问题,因为支持什么样的模式,完全看数据库驱动的实现方式了。
- %s 这种占位符的,叫 format 模式,一般可以使用 %(name)s 这种格式来使用字典参数
- ? 这种占位符的,叫 qmark 模式,一般会使用 :name 这种格式来使用字典参数,SQLAlchemy 看起来就是用的这种
还有一种叫 numeric 模式的,具体可以看下这个 paramstyle 的说明
查询数据库驱动支持什么样的,这里只看下 pymysql:
In[21]: import pymysql
In[22]: pymysql.paramstyle
Out[22]: 'pyformat'
以及,pymysql 也在 execute 文档中明确提到这么一句:
If args is a list or tuple, %s can be used as a placeholder in the query. If args is a dict, %(name)s can be used as a placeholder in the query.
这样,就能确定可以使用 %(name)s 这种格式来使用字典参数了:
params = {'limit': 10}
sql = 'select * from test limit %(limit)s'
cursor.execute(sql, params)