次のロジックはmysqldbモジュールで機能します( 1つの接続に対してpython mysqldb複数のカーソル を参照)が、cursor2.execute(sql)のmysql.connectorで次のエラーが発生します
「未読の結果が見つかりました。」
結合を使用してこれら2つの単純なSQLステートメントを組み合わせ、2番目のカーソルの必要性を回避できることを理解していますが、実際の例はより複雑で、2番目の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()
MySQL Connector/Pythonは、デフォルトでは非バッファリングです。これは、データが自動的にフェッチされないことを意味し、「消費」する必要がありますall行。 (そのドライバーはデフォルトでバッファリングされているため、MySQLdbで動作します。)
Connector/Pythonを使用するには、イテレータとして使用するカーソルに対してTrueに設定されたbuffered-argumentを使用する必要があります。 OPの質問では、これはcursor1
になります。
cursor1 = db.cursor(buffered=True)
cursor2 = db.cursor()
buffered=True
を接続引数として使用して、すべてのカーソルバッファリングをこの接続バッファリングによってインスタンス化することもできます。