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

Posted

技术标签:

【中文标题】Python MySQL连接器在游标循环中执行第二条sql语句?【英文标题】:Python MySQL Connector executing second sql statement within cursor loop? 【发布时间】:2014-05-20 05:07:11 【问题描述】:

以下逻辑适用于 mysqldb 模块(请参阅python mysqldb multiple cursors for one connection),但在 cursor2.execute(sql) 上使用 mysql.connector 时出现以下错误

“找到未读结果。”

我意识到我可以使用连接来组合这两个简单的 sql 语句并避免需要第二个游标,但我的实际示例更复杂,需要第二个 sql 语句。

假设我需要执行 2 个单独的 sql 语句(1 个用于循环,1 个在循环内),应该如何使用 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】:

默认情况下,MySQL 连接器/Python 是非缓冲的。这意味着数据不会自动获取,您需要“使用”所有行。 (它适用于 MySQLdb,因为该驱动程序默认情况下正在缓冲。)

使用连接器/Python,您必须使用设置为 True 的缓冲参数作为迭代器。在 OP 的问题中,这将是 cursor1:

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

您还可以使用buffered=True 作为连接参数,以使所有游标缓冲都由该连接缓冲实例化。

【讨论】:

谢谢吉尔特!默认情况下缓冲和非缓冲之间的权衡决定是什么?从用户的角度来看,模仿mysqldb似乎更好? 恕我直言,默认情况下不缓冲在获取大量数据时更安全。当我知道只有很小的结果时,我会打开缓冲。这在连接器/Python 中不会改变。 再次感谢吉尔特!只是想明白。 :) 很遗憾,buffered=True 不能与 prepared=True 结合使用——“ValueError:光标在给定条件下不可用:已缓冲,已准备好”

以上是关于Python MySQL连接器在游标循环中执行第二条sql语句?的主要内容,如果未能解决你的问题,请参考以下文章

python中脚本怎么执行sql语句?

python中脚本怎么执行sql语句?

sqlserver中游标循环中只更新当前行的方法

Python3操作MySQL数据库

如何使用 python 获取对象 MySQL:连接器游标

MySQL与python交互