pymysql returns 最后一行中的 WHERE IN 子句

WHERE IN clause in pymysql returns last row

考虑 6 行的 table 用户

   +_______________________+
   |     userid |  name    |
   +-----------------------+
   |       1    | john     |
   |       2    | steve    |
   |       3    | joe      |
   |       4    | jason    |
   |       5    | abraham  |
   |       6    | leonard  |
   +-----------------------+

我正在使用以下 SQL 查询:

SELECT userid,name FROM users where userid IN (2,3,4,5);

其中 returns 4 行 -

   |       2    | steve    |
   |       3    | joe      |
   |       4    | jason    |
   |       5    | abraham  |

Pymysql等效代码如下:

def get_username(user_ids):
    data=[]
    conn = init_db()
    cur = conn.cursor(pymysql.cursors.DictCursor)
    cur.executemany("SELECT userid,name from users WHERE userid IN (%s)",user_ids)
    rows=cur.fetchall()
    for row in rows:
        data.append([row['userid'],row['name']])
    cur.close()
    conn.close()
    return data

user_ids=[2,3,4,5]
get_usernames(user_ids)

这段代码只是 returns 最后一行 [[5,abraham]] 。我怎样才能获取所有这些行?

我的第一个猜测是与 SELECT 语句相关。 您可以尝试这种生成查询的方式吗?

def get_username(user_ids):
    data=[]
    conn = init_db()
    cur = conn.cursor(pymysql.cursors.DictCursor)
    cur.executemany("SELECT userid,name from users WHERE userid IN "+"("+','.join(str(e) for e in user_ids)+")")
    rows=cur.fetchall()
    for row in rows:
        data.append([row['userid'],row['name']])
    cur.close()
    conn.close()
    return data

user_ids=[2,3,4,5]
get_usernames(user_ids)

这是 .executemany() 的(部分记录的)行为:

Help on method executemany in module pymysql.cursors:

executemany(self, query, args) method of pymysql.cursors.Cursor instance

Run several data against one query

:param query: query to execute on server

:param args: Sequence of sequences or mappings. It is used as parameter.

:return: Number of rows affected, if any.

This method improves performance on multiple-row INSERT and REPLACE. Otherwise it is equivalent to looping over args with execute().

所以您在这里想要的是 cursor.execute() - 但是,您需要做更多的工作来构建 SQL 查询:

user_ids = (2, 3, 4, 5)
placeholders = ", ".join(["%s"] * len(user_ids)) 
sql = "SELECT userid,name from users WHERE userid IN ({})".format(placeholders)
cursor.execute(sql, user_ids)
data = list(cursor)

请注意,游标是可迭代的,因此您无需显式调用 cursor.fetchall() 然后对结果进行迭代,您可以直接对游标进行迭代。另请注意,如果您想要一个 (id, name) 元组列表,使用 DictCursor 只是对 CPU 循环的双重浪费(一次用于构建字典,一次用于从中重建元组) ,您可以只使用默认光标和 return list(cursor)