2012-10-12 7 views
19

Ich möchte das Ergebnis der Fetchall-Operation in einer Liste anstelle von Tupel Tupel oder Tupel von Wörterbüchern erhalten. Zum BeispielPython MySQLDB: Holen Sie sich das Ergebnis von fetchall in einer Liste

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

nun das Problem, das sich ergebende Zeile ist entweder ((123,), (234)) oder ({ 'id': 123}, { 'id': 234}) Ich suche nach 123234 oder 123234. Am besten, wenn ich beim Parsing des Resulsets sparen kann. Vielen Dank im Voraus

+0

Wahrscheinlich eine benutzerdefinierte Cursor-Klasse zu tun hat müssen liefern. Die django db Backends machen das, also könnt ihr dort nach Inspiration suchen. Zum Beispiel wird "django.db.backends.mysql.base.CursorWrapper" oben auf dem MySQL Cursor verwendet, aber ich bin mir nicht sicher, wo das registriert ist. Dies kann bedeuten, dass Sie ein benutzerdefiniertes DB-Backend bereitstellen, das Ihren benutzerdefinierten Cursor zurückgibt. Es ist wahrscheinlich einfacher, die Daten zu analysieren, die Sie benötigen, wenn Sie darauf zugreifen. – dokkaebi

Antwort

38

Und was ist mit List Comprehensions? Wenn das Ergebnis ist ((123,), (234,), (345,)):

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

Wenn das Ergebnis ist ({'id': 123}, {'id': 234}, {'id': 345}):

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

Alter Ich erwähnte es, ich versuche das zu vermeiden. Ich hatte gehofft, der Cursor könnte so programmiert werden, dass das Ergebnis direkt in der Liste abgerufen werden kann. –

+1

Also, wenn dieses Szenario nur ein Beispiel ist, wie planen Sie das mit Abfragen, die mehr als ein Feld haben? Deshalb erhalten Sie zuerst ein Tupel Tupel –

+0

Wer hat gesagt, es ist ein Beispiel? Ich möchte nur eine einzige Spalte mit IDs abrufen und die Zeilenanzahl in Millionen. Ich möchte eine Nachbearbeitung der Daten vornehmen, weshalb ich versuche, einen Weg zu finden, um diese teure Operation zu vermeiden. –

1

Wenn nur ein Feld ist, kann ich diese verwenden, um eine Liste von Datenbank zu machen:

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

Ich bin mir sicher, dass Sie nach all dieser Zeit dieses Problem jedoch für einige Leute gelöst haben, die das nicht können wissen, wie die Werte eines Cursors als Wörterbuch erhalten mit MySQLdb, können Sie diese Methode here verwenden Sie:

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

Dieses alte Q oben auf Google kommt, während db Abfragen der Suche nach Abflachen, so dass hier weitere Vorschläge sind. ..

Betrachten Sie eine schnelle list-flattening iterator.

Andere Antworten verwenden fetchall(), die zuerst alle Zeilen im Speicher lädt, dann iteriert, um eine neue Liste zu erstellen. Könnte ineffizient sein. Könnte mit MySQL verbinden sogenannte 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() 

Aber die Frage ist auch Django markiert, die einen schönen single field query flattener

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

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

Ein paar Jahre zu spät, aber das ist, was OP wollte - erstellen Sie eine Liste ohne Verwendung von fetch all() aufgrund der Anzahl seiner Datenpunkte. –

Verwandte Themen