web-dev-qa-db-ja.com

Python MySQL Connectorはカーソルループ内で2番目のSQLステートメントを実行していますか?

次のロジックは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()
14
panofish

MySQL Connector/Pythonは、デフォルトでは非バッファリングです。これは、データが自動的にフェッチされないことを意味し、「消費」する必要がありますall行。 (そのドライバーはデフォルトでバッファリングされているため、MySQLdbで動作します。)

Connector/Pythonを使用するには、イテレータとして使用するカーソルに対してTrueに設定されたbuffered-argumentを使用する必要があります。 OPの質問では、これはcursor1になります。

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

buffered=Trueを接続引数として使用して、すべてのカーソルバッファリングをこの接続バッファリングによってインスタンス化することもできます。

16
geertjanvdk