DictCursor chyba nie działa pod psycopg2

Nie pracowałem wcześniej z psycopg2, ale próbuję zmienić fabrykę kursorów na DictCursor, aby fetchall lub fetchone zwróciły słownik zamiast listy.

Stworzyłem skrypt testowy, aby wszystko było proste i przetestować tylko tę funkcjonalność. Oto mój mały kod, który moim zdaniem powinien zadziałać

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

Zmienna res jest zawsze listą, a nie słownikiem, jak bym się spodziewał.

Obecne obejście, które zaimplementowałem, polega na użyciu tego funkcja, która buduje słownik i uruchamia przez niego każdy wiersz zwracany przez fetchall.

def build_dict(cursor, row):
    x = {}
    for key,col in enumerate(cursor.description):
        x[col[0]] = row[key]
    return d

Python to wersja 2.6.7, a psycopg2 to wersja 2.4.2.

Author: Jim, 2011-07-18

6 answers

res = cur.fetchall()

Tworzy res listę psycopg2.extras.DictRows.


Alternatywnie, zamiast wywoływać cur.fetchall możesz skorzystać z faktu, że cur jest iterowalne:

cur.execute("SELECT * from review")
for row in cur:
    print(row['column_name'])

I dzięki temu będziesz mógł uzyskać dostęp do danych z dict-podobną składnią.

 39
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-30 01:15:26

Użycie RealDictCursor:

import psycopg2.extras

cur = conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
cur.execute("SELECT * from review")
res = cur.fetchall()    

To daje listę z wierszami jako prawdziwymi słownikami Pythona zamiast "advanced psycopg2 list".

 112
Author: kerma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-09 11:55:53

Innym rozwiązaniem byłoby użycie o nazwie krotka kursor ponieważ prawdziwy kursor Dict złamie każde zapytanie, które używa wskaźników całkowitych, jak wyjaśniono w jego dokumentacji.

Z nazwanymi kursorami krotki, możesz uzyskać do nich dostęp za pomocą składni kropki w następujący sposób:

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
To utrzymuje porządek i nic nie zepsuje, o ile wiem.
 15
Author: Brideau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-25 18:02:49

Chociaż jest to starsze pytanie, wciąż pojawia się w google, więc pomyślałem, że dodam mój kod do tego dla każdego innego pochodzącego z dużego G.

Dla mnie mam wiele wierszy, które chciałbym wrócić z powrotem do słownika i najlepiej nie chcę używać pętli lub podobnego do ustawiania klucza z pola w bazie danych..

Więc używając {[2] } mogę wykonać następujące czynności.

Wiersze Tabeli Do Słownika


pgCursor = Conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
pgCursor.execute("SELECT * FROM tablename;",([]))
dictRows = {n['id']: n for n in pgCursor}

Funkcja I Wywołanie It

#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;")

Podczas gdy to jest za pomocą x W pętli y, jego pythonic o ile mogę powiedzieć....Mam nadzieję, że to będzie pomocne dla niektórych tam.

 5
Author: Angry 84,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 03:07:51

Oprócz korzystania z funkcji RealDictCursor, możesz również poprosić o wszystkie kolumny (za pomocą symbolu * po wybraniu), jak to jest zrobione w odpowiedzi.

Nie interesowały mnie niektóre kolumny wyniku, ponieważ miały one znane wartości już stosowane w warunkach gdzie. Ale SELECT (..., ..., ..., ...) FROM ... WHERE ... wariant nie dał mi słowników.

Pozdrawiam ! Harley
 0
Author: Hans Davidson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-11 12:29:49

Więc aby to działało jak mysql Wersja kursora słownika będziesz musiał owinąć go w inną funkcję lub kod. Wejdę na forum i zasugeruję im to do przyszłych wdrożeń ich kodu, aby zwrócili słownik, gdy wywołanie fetchall () zostanie użyte z kursorem słownika. Oto przykładowy kod, którego możesz użyć, aby go naprawić:

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]

Ten kod sprawia, że jest on w tym samym formacie, co wersja MySQL kursora słownika za pomocą fetchall (). Nie wiem dlaczego oni zaimplementowano go inaczej, ale to pomoże ci uzyskać ten sam wynik rzeczywistego słownika Pythona, a nie listę w przypadku fetchall ().

 0
Author: Josh Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-28 17:23:08