Skriptanfänger schrieb:
>
1 | > for row in rows:
|
2 | > print row["id"]
|
3 | >
|
>
> allerdings bekomme ich nun folgenden Fehler:
>
>
1 | > Traceback (most recent call last):
|
2 | > File "test.py", line 15, in <module>
|
3 | > print row["id"]
|
4 | > TypeError: tuple indices must be integers, not str
|
5 | >
|
>
> Aber "id" ist vom Typ "int(10) unsigned" . Was ist falsch?
Was flashc ist, ist "row": das ist ein Tupel und kein Dict. Ein Tupel
kann aber nur über den (Integer-)Index des gesuchten Elements
angesprochen werden, Du hingegen versuchst, das mit einem Dict-Key zu
machen, etwa so:
1 | meinTupel = (1, 2, 3, 4)
|
2 | print meinTupel['foo']
|
Du hast jetzt zwei Möglichkeiten: entweder Du benutzt Integer-Indizes,
also statt 'row["id"]' eben 'row[0]' -- gesetzt, die Spalte 0 ist die
Spalte, die Deine id enthält. Dann würde ich aber sicherstellen, daß die
Spalte 0 auch tatsächlich die id enthält, also statt "SELECT * FROM"
lieber etwas wie "SELECT id, ... FROM" schreiben -- sonst kann Dir das
nämlich zu sehr interessanten Problemen kommen, wenn Du irgendwann mal
die Struktur Deiner Tabelle änderst und id dann nicht mehr die erste
Spalte ist.
Die andere Möglichkeit ist, einen DictCursor zu benutzen. wie ihn jeder
DBAPI-2.0-kompatible Python-Datenbanktreiber anbietet. Dann erzeugst Du
Deinen Cursor nicht mehr mit
sondern mit
1 | curs = con.cursor(MySQLdb.cursors.DictCursor)
|
und erhälst dann als "row" keine Tupel mehr, sondern ein Dict.
Achtung: in Abhängigkeit von der abgefragten Datenmenge und der Anzahl
und Länge Deiner Spaltennamen kann ein fetchall() auf einen DictCursor
durchaus mehr Arbeitsspeicher benötigen als der Standard-Tuple-Cursor.
Besser als
1 | cur.execute(...)
|
2 | res = cur.fetchall()
|
3 | for row in rows:
|
4 | process(row)
|
ist daher meistens, das Iterator-Interface des Cursors zu benutzen:
1 | cur.execute(...)
|
2 | for row in cur:
|
3 | process(row)
|