DictCursor не работает под psycopg2 - PullRequest
50 голосов
/ 19 июля 2011

Я раньше не работал с psycopg2, но я пытаюсь изменить фабрику курсоров на DictCursor, чтобы fetchall или fetchone возвращали словарь вместо списка.

Я создал тестовый скрипт длявсе просто и только проверить эту функциональность.Вот мой маленький кусочек кода, который, как мне кажется, должен работать

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

Переменная res всегда является списком, а не словарем, как я ожидал.

Текущий обходной путь, который я реализовалиспользовать эту функцию, которая создает словарь и запускает через него каждую строку, возвращаемую fetchall.

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

Python версии 2.6.7 и psycopg2 версии 2.4.2.

Ответы [ 6 ]

89 голосов
/ 10 февраля 2012

Использовать RealDictCursor:

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

Это дает вам список с строками в виде реальных словарей Python вместо «расширенного списка psycopg2».

26 голосов
/ 19 июля 2011
res = cur.fetchall()

составляет res список psycopg2.extras.DictRow с.


В качестве альтернативы, вместо вызова cur.fetchall вы можете воспользоваться тем, что cur является итеративным:

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

и, таким образом, вы сможете получить доступ к данным с dict -подобным синтаксисом.

6 голосов
/ 25 января 2015

Другим решением будет использование Именованного Курсора Кортежей , так как Реальный Dict Курсор прервет любой запрос, который использует целочисленные знаки, как объяснено в его документации.

С Именованными Курсорами Tuple, выможет получить к ним доступ с точечным синтаксисом, например, так:

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

Насколько я знаю, все будет в порядке и ничего не сломается.

3 голосов
/ 19 октября 2016

Хотя это старый вопрос, он все еще появляется в Google, поэтому я решил добавить свой код к нему для всех, кто приезжает с большой G.

Для меня у меня есть несколько строк, которые яхотел бы вернуться обратно в словарь и в идеале не хочет использовать цикл или аналогичный для установки ключа из поля в базе данных.

Так что используя dict comprehension syntax я могу сделать следующее.

Строки таблицы в словаре


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

Функция и вызов

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

Хотя здесь используется цикл for x in y, насколько я могу судить, его pythonic .... Надеюсь, это поможет некоторым там.

0 голосов
/ 28 декабря 2017

Таким образом, чтобы сделать эту работу похожей на mysql-версию курсора Dictionary, вам нужно будет обернуть его в другую функцию или код. Я пойду на форумы и предложу им это для будущих развертываний их кода, чтобы они возвращали словарь, когда вызов fetchall () используется с курсором словаря. Вот пример кода, который вы можете использовать для исправления:

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]

Этот код делает его в том же формате, что и MySQL-версия курсора словаря, используя fetchall (). Не уверен, почему они реализовали это по-разному, но это поможет вам получить тот же вывод фактического словаря Python, а не списка в случае fetchall ().

0 голосов
/ 11 июля 2013

Помимо использования функции RealDictCursor, вам также может потребоваться запросить все столбцы (используя символ * после выбора), как это делается в ответе.

Меня не интересовали некоторые столбцы результата, так как они имели известные значения уже используется в ГДЕ условиях. Но SELECT (..., ..., ..., ...) FROM ... WHERE ... вариант не дал мне словари.

С наилучшими пожеланиями! Harley

...