2012-10-12 12 views
19

Vorrei ottenere il risultato dell'operazione fetchall in un elenco invece di tuple di tuple o tuple di dizionari. Ad esempio,Python MySQLDB: Ottieni il risultato di un risultato in un elenco

cursor = connection.cursor() #Cursor could be a normal cursor or dict cursor 
query = "Select id from bs" 
cursor.execute(query) 
row = cursor.fetchall() 

Ora, il problema è la riga risultante è o ((123,), (234,)) o ({ 'id': 123}, { 'id': 234}) Quello che sto cercando è (123,234) o [123,234]. Siate i migliori se posso risparmiare parsing del resulset. Grazie in anticipo

+0

Probabilmente hanno a disposizione una classe cursore personalizzato per fare questo. I backend django db fanno questo, quindi puoi cercare l'ispirazione lì. Ad esempio, 'django.db.backends.mysql.base.CursorWrapper' è usato sopra il Cursore MySQL, ma non sono sicuro di dove sia registrato. Potrebbe significare fornire un back-end db personalizzato che restituisca il Cursore personalizzato. Probabilmente sarà più semplice analizzare i dati necessari per accedervi. – dokkaebi

risposta

38

E per quanto riguarda la comprensione delle liste? Se il risultato è ((123,), (234,), (345,)):

>>> row = [item[0] for item in cursor.fetchall()] 
>>> row 
[123, 234, 345] 

Se il risultato è ({'id': 123}, {'id': 234}, {'id': 345}):

>>> row = [item['id'] for item in cursor.fetchall()] 
>>> row 
[123, 234, 345] 
+4

Amico, l'ho menzionato, sto cercando di evitarlo. Speravo che il cursore potesse essere programmato in modo che il risultato potesse essere recuperato direttamente nell'elenco. –

+1

Quindi, se questo scenario è solo un esempio, come pensi di farlo con query che hanno più di un campo? Ecco perché ottieni una tupla di tuple nel primo caso –

+0

Chi ha detto che è un esempio? Voglio solo recuperare una singola colonna di ID e il conteggio delle righe è in milioni. Voglio fare un post processing sui dati ed è per questo che sto cercando di capire un modo per evitare questa operazione costosa. –

1

Se v'è un solo campo, posso usare questo per fare un elenco dal database:

def getFieldAsList(): 
    kursor.execute("Select id from bs") 
    id_data = kursor.fetchall() 
    id_list = [] 
    for index in range(len(id_data)): 
     id_list.append(id_data[index][0]) 
    return id_list 
-4
cursor.execute("""Select * From bs WHERE (id = %s)""",(id)) 

cursor.fetchall() 
13

Sono sicuro che dopo tutto questo tempo, hai risolto questo problema, tuttavia, per alcune persone che potrebbero non sapere come ottenere i valori di un cursore come un dizionario utilizzando MySQLdb, è possibile utilizzare questo metodo trovato here:

import MySQLdb as mdb 

con = mdb.connect('localhost', 'testuser', 'test623', 'testdb') 

with con: 

    cur = con.cursor(mdb.cursors.DictCursor) 
    cur.execute("SELECT * FROM Writers LIMIT 4") 

    rows = cur.fetchall() 

    for row in rows: 
     print row["Id"], row["Name"] 
7

Questa vecchia Q arriva su Google durante la ricerca per l'appiattimento query db, per cui qui sono più suggerimenti. ..

Considerare un veloce list-flattening iterator.

Altre risposte utilizzano fetchall() che prima carica tutte le righe in memoria, quindi esegue un'iterazione per creare un nuovo elenco. Potrebbe essere inefficiente. Potrebbe combinano con MySQL cosiddetto server side cursor:

# assume mysql on localhost with db test and table bs 
import itertools 
import MySQLdb 
import MySQLdb.cursors 

conn = MySQLdb.connect(host='localhost',db='test', 
      cursorclass=MySQLdb.cursors.SSCursor) 
cursor = conn.cursor() 
# insert a bunch of rows 
cursor.executemany('INSERT INTO bs (id) VALUES (%s)',zip(range(1,10000))) 
conn.commit() 
# retrieve and listify 
cursor.execute("select id from bs") 
list_of_ids = list(itertools.chain.from_iterable(cursor)) 
len(list_of_ids) 
#9999 
conn.close() 

Ma la questione è anche etichettato Django, che ha una bella single field query flattener

class Bs(models.Model): 
    id_field = models.IntegerField() 

list_of_ids = Bs.objects.values_list('id_field', flat=True) 
+0

Un paio d'anni di ritardo, ma questo è ciò che l'OP stava chiedendo: creare un elenco senza utilizzare fetch all() a causa del numero dei suoi punti dati. –

Problemi correlati