Ich habe vorher noch nicht mit psycopg2 gearbeitet, aber ich versuche, die Cursorfabrik in DictCursor zu ändern, sodass fetchall oder fetchone anstelle einer Liste ein Wörterbuch zurückgibt.
Ich habe ein Testskript erstellt, um die Dinge zu vereinfachen und nur diese Funktionalität zu testen. Hier ist mein kleiner Code, der meiner Meinung nach funktionieren sollte
import psycopg2
import psycopg2.extras
conn = psycopg2.connect("dbname=%s user=%s password=%s" % (DATABASE, USERNAME, PASSWORD))
cur = conn.cursor(cursor_factory = psycopg2.extras.DictCursor)
cur.execute("SELECT * from review")
res = cur.fetchall()
print type(res)
print res
Die res-Variable ist immer eine Liste und kein Wörterbuch, wie ich es erwarten würde.
Eine aktuelle Problemumgehung, die ich implementiert habe, besteht darin, diese Funktion zu verwenden, die ein Wörterbuch erstellt, und jede Zeile auszuführen, die von fetchall zurückgegeben wird.
def build_dict(cursor, row):
x = {}
for key,col in enumerate(cursor.description):
x[col[0]] = row[key]
return d
Python ist Version 2.6.7 und Psycopg2 ist Version 2.4.2.
res = cur.fetchall()
macht res
eine Liste von psycopg2.extras.DictRow
s.
Anstatt cur.fetchall
aufzurufen, können Sie alternativ die Tatsache nutzen, dass cur
eine Iteration ist:
cur.execute("SELECT * from review")
for row in cur:
print(row['column_name'])
und somit können Sie mit dict
- artiger Syntax auf die Daten zugreifen.
Verwenden Sie RealDictCursor:
cur = conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
cur.execute("SELECT * from review")
res = cur.fetchall()
Dadurch erhalten Sie eine Liste mit Zeilen als echte Python-Wörterbücher anstelle von "Erweiterte Psycopg2-Liste".
Eine andere Lösung wäre die Verwendung des benannten Tupel-Cursors , da der Real Dict-Cursor jede Abfrage unterbricht, die Ganzzahl-Indikatoren verwendet, wie in der Dokumentation beschrieben.
Mit Named Tuple Cursors können Sie wie folgt auf die Punktsyntax zugreifen:
import psycopg2
import psycopg2.extras
cur = conn.cursor(cursor_factory = psycopg2.extras.NamedTupleCursor)
cur.execute("SELECT * from review")
res = cur.fetchone()
res.key1
res.key2
Das hält die Dinge aufgeräumt und bricht nichts, soweit ich weiß.
Obwohl dies eine ältere Frage ist, kommt sie immer noch in google auf, also dachte ich, ich würde meinen Code für alle anderen hinzufügen, die vom großen G kommen.
Für mich habe ich mehrere Zeilen, die ich gerne in ein Wörterbuch zurückbringen möchte. Idealerweise möchte ich keine Schleife oder ähnliches verwenden, um den Schlüssel aus einem Feld in der Datenbank zu setzen.
Mit dict comprehension syntax
kann ich also folgendes tun.
Tabellenzeilen ins Wörterbuch
pgCursor = Conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
pgCursor.execute("SELECT * FROM tablename;",([]))
dictRows = {n['id']: n for n in pgCursor}
Funktion & Aufruf
#NOTE this is using a class object hence the self param
def DBTableToDictByID(self, squery):
self.Pointer.execute(squery,([]))
return {n['id']: n for n in self.Pointer}
dictRows = self.DBTableToDictByID("SELECT * FROM tablename;")
Während dies eine for x in y -Schleife verwendet, ist Pythonic soweit ich das beurteilen kann ... Hoffentlich wird dies einigen da draußen helfen.
Zusätzlich zur Verwendung der RealDictCursor-Funktion müssen Sie möglicherweise auch nach allen Spalten (Mit dem Symbol * nach dem Auswählen) fragen, wie in der Antwort beschrieben.
Ich interessierte mich nicht für einige Spalten des Ergebnisses, da sie bereits bekannte Werte hatten, die unter WHERE-Bedingungen verwendet wurden. Aber die SELECT (..., ..., ..., ...) FROM ... WHERE ...
Variante hat mir keine Wörterbücher gegeben.
Beste Grüße! Harley
Um diese Funktion wie die MySQL-Version des Dictionary-Cursors auszuführen, müssen Sie sie in eine andere Funktion oder einen anderen Code einbetten. Ich werde in die Foren gehen und ihnen das für zukünftige Bereitstellungen ihres Codes vorschlagen, um ein Wörterbuch zurückzugeben, wenn der Aufruf von fetchall () mit dem Wörterbuchcursor verwendet wird. Hier ist ein Beispielcode, mit dem Sie das Problem beheben können:
cursor.execute(query)
# Python 2.7 and beyond with dictionary comprehension
results = [{key:value for key,value in row.iteritems()} for row in cursor]
# Python 2.6 and before
# results = [dict((key,value) for key,value in row.iteritems()) for row in cursor]
Durch diesen Code wird das gleiche Format verwendet wie die MySQL-Version des Wörterbuchcursors mit fetchall (). Sie sind sich nicht sicher, warum sie anders implementiert wurden. Dies hilft Ihnen jedoch, die gleiche Ausgabe eines tatsächlichen Python-Wörterbuchs anstelle einer Liste im Fall fetchall () zu erhalten.