2013-01-07 3 views
5

Ho un un codice come questo:Fetchall restituisce solo una colonna in Python?

db = MySQLdb.connect(user='root', db='galaxy', passwd='devil', host='localhost') 
cursor = db.cursor() 
cursor.execute('SELECT username, password FROM galaxy_user') 
names = [row[0] for row in cursor.fetchall()] 
passw = [password[1] for password in cursor.fetchall()] 
db.close() 

Il problema è che posso accedere solo sia nomi o PASSW dal seguente codice. Con questo posso solo ottenere il nome utente. Ottengo la lista vuota per passw. Ora se cambio questo tipo:

passw = [row[1] for row in cursor.fetchall()] 
names = [password[1] for password in cursor.fetchall() 

Ottengo il valore di passw ma i nomi sono elenchi vuoti. Cosa sta succedendo?

risposta

13

Dopo ogni cursor.execute è possibile utilizzare cursor.fetchall una sola volta. "Esaurisce" il cursore, ottiene tutti i suoi dati e quindi non può essere "letto" di nuovo.

Con questo codice di leggere tutti i dati allo stesso tempo:

db = MySQLdb.connect(user='root', db='galaxy', passwd='devil', host='localhost') 
cursor = db.cursor() 
cursor.execute('SELECT username, password FROM galaxy_user') 
names, passw = zip(*cursor.fetchall()) 
db.close() 

Un'altra possibilità potrebbe essere quella di memorizzare tutti i dati in un elenco e poi leggerlo come se si trattasse di un cursore:

records = cursor.fetchall() 
names = [record[0] for record in records] 
passw = [record[1] for record in records] 

O che dire di un dizionario (nome -> password)?

user_pass = dict(cursor.fetchall()) 

o semplicemente (come suggerito @JonClemens):

user_pass = dict(cursor) 
+2

Penso che la chiave qui è che '.fetchall()' sembra un po 'ridondante, come il cursore dovrebbe essere iterabile ... entrambi i casi, 'list (cursor)' o mi piace l'idea 'dict (cursor)' :) –

+0

@eumiro, ho appena provato usando Python cx_Oracle: records = cursor.fetchall() names = [record [0] per record nei record] passw = [record [1] per record in record] e il nome è Nessuno. Grazie – Frank