Python MySQL 连接器在游标循环中执行第二个 SQL 语句?

16 投票
1 回答
19316 浏览
提问于 2025-04-18 01:45

下面的逻辑在mysqldb模块中是可以正常工作的(可以参考这个链接:python mysqldb多个游标在一个连接中),但是我在使用mysql.connector时,在执行cursor2.execute(sql)时遇到了以下错误:

“发现未读结果。”

我意识到可以使用连接(join)将这两个简单的sql语句合并,这样就不需要第二个游标了,但我实际的例子更复杂,需要第二个sql语句。

假设我需要执行两个独立的sql语句(一个在循环外,一个在循环内),那么在mysql.connector模块中应该怎么做呢?

import datetime
import mysql.connector

db = mysql.connector.connect(user='alan', password='please', host='machine1', database='mydb')

cursor1 = db.cursor()
cursor2 = db.cursor()

sql = """
SELECT userid, 
       username,
       date
  FROM user
 WHERE date BETWEEN %s AND %s
"""

start_date = datetime.date(1999, 1, 1)
end_date   = datetime.date(2014, 12, 31)

cursor1.execute(sql, (start_date, end_date))

for (userid, username, date) in cursor1:

    sql = """
        select count(*)
        from request
        where assigned = '%s'
    """ % (userid)

    cursor2.execute(sql)
    requestcount = cursor2.fetchone()[0]

    print userid, requestcount

cursor2.close()
cursor1.close()
db.close()

这个mysqldb版本运行得很好:

import datetime
import MySQLdb 

db = MySQLdb.connect(user='alan', passwd='please', host='machine1', db='mydb')

cursor1 = db.cursor()
cursor2 = db.cursor()

sql = """
SELECT userid, 
       username,
       date
  FROM user
 WHERE date BETWEEN %s AND %s
"""

start_date = datetime.date(1999, 1, 1)
end_date   = datetime.date(2014, 12, 31)

cursor1.execute(sql, (start_date, end_date))

for (userid, username, date) in cursor1:

    sql = """
        select count(*)
        from request
        where assigned = '%s'
    """ % (userid)

    cursor2.execute(sql)
    requestcount = cursor2.fetchone()[0]

    print userid, requestcount

cursor2.close()
cursor1.close()
db.close()

1 个回答

21

MySQL Connector/Python 默认情况下是非缓冲的。这意味着数据不会自动获取,你需要手动“消费”所有的行。(这在 MySQLdb 中是可以的,因为那个驱动默认是缓冲的。)

使用 Connector/Python 时,你需要将游标的缓冲参数设置为 True,才能把它当作迭代器使用。在提问者的问题中,这个游标就是 cursor1

cursor1 = db.cursor(buffered=True)
cursor2 = db.cursor()

你也可以在连接时使用 buffered=True 这个参数,这样通过这个连接创建的所有游标都会启用缓冲。

撰写回答