2014-04-07 7 views
8

Il seguente logica funziona con il modulo MySQLdb (vedi python mysqldb multiple cursors for one connection), ma sto ottenendo il seguente errore con mysql.connector sul cursor2.execute (SQL)Python MySQL Connector esegue la seconda istruzione sql all'interno del loop del cursore?

"Risultato Unread trovato."

Mi rendo conto che posso utilizzare un join per combinare queste due semplici istruzioni sql ed evitare la necessità di un secondo cursore, ma il mio esempio del mondo reale è più complesso e richiede una seconda istruzione sql.

Supponendo che è necessario eseguire 2 istruzioni SQL separate (1 per il ciclo e 1 all'interno del ciclo), come dovrebbe essere fatto con il modulo 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() 

Questa versione mysqldb funziona bene:

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() 

risposta

10

MySQL Connector/Python è, per impostazione predefinita, non buffering. Ciò significa che i dati non vengono recuperati automaticamente e devi "consumare" tutte le righe. (Funziona con MySQLdb perché il driver è di tipo buffering per impostazione predefinita.)

Utilizzando Connector/Python è necessario utilizzare l'argomento buffer impostato su True per il cursore utilizzato come iteratore. Nella domanda del PO, questo sarebbe cursor1:

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

È inoltre possibile utilizzare buffered=True come argomento di connessione per rendere tutto il buffering del cursore istanziato da questo buffer di collegamento.

+0

Grazie Geert! Qual è la decisione di trade-off tra buffer e non-buffered per impostazione predefinita? Dal punto di vista dell'utente, sembrerebbe più bello imitare mysqldb? – panofish

+0

IMHO, non-buffering di default è più sicuro quando si recuperano molti dati. Quando so che ci saranno solo piccoli risultati, accenderò il buffering. Questo non cambierà in Connector/Python. – geertjanvdk

+0

Grazie ancora Geert! Volevo solo capire. :) – panofish