pymysql选择带有可变数量的参数

时间:2016-09-05 16:23:33

标签: python pymysql

我读了几个例子,说明pymysql“select in”应该如何工作。所以,这个例子很好用:

 sql_select = 'SELECT a.user_id, AVG(a.rcount) AS \'average\' ' \
                 'FROM (SELECT user_id, item_id, count(*) AS rcount ' \
                 'FROM submission AS qsm ' \
                 'JOIN metadata as qm   ' \
                 'ON qsm.item_id = qm.id ' \
                 'WHERE qsm.item_id NOT IN (1, 2, 5, 6, 7, 147, 148) ' \
                 'AND DATE(FROM_UNIXTIME(submission_time)) BETWEEN %s AND %s ' \
                 'AND qm.type != \'survey\' ' \
                 'GROUP BY user_id, item_id ' \
                 'ORDER BY user_id) a ' \
                 'GROUP BY a.user_id'
    args = [course_start, course_end]
    cur.execute(sql_select, args)

但是,我还想为这个“NOT IN”部分添加另一个论点。这里的问题是这个列表是可变的,所以不太确定如何处理这个。

2 个答案:

答案 0 :(得分:1)

With PyMySQL version 0.7.9:

cells = ('cell_1', 'cell_2')
cursor.execute('select count(*) from instance where cell_name in %(cell_names)s;', {'cell_names': cells})
# or alternately
cursor.execute('select count(*) from instance where cell_name in %s;', [cells])

The PyMySQL execute documentation describes the two possible forms:

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.

答案 1 :(得分:0)

虽然这个问题很老,但考虑到当前和现在旧的 MySQL 库的多样性以及它们如何进行参数处理,很容易混淆。上面的问题是针对 PyMySQL,而不是针对 MySQLConnector。尽管问题评论中的参考提供了很好的指导,但下面解决了 PyMySQL==1.0.2 策略,该策略也应与 MySQLConnector 一起使用。

  1. 创建参数扩展
  2. 将它们格式化为查询字符串
  3. 将解压值传递给 cursor.execute() 以进行 sql 注入检查

看起来像:

    in_params = [1,2,3,4]
    with closing(db.cursor()) as c:
        expansions = ",".join(["%s"] * len(in_params))
        q = "select 1 from information_schema.processlist where id in ({}) and host = %s".format(expansions)
        c.execute(q, (*in_params, 'localhost'))
        print(c._last_executed)

这将提供:

select 1 from information_schema.processlist where id in (1,2,3,4) and host = 'localhost'