DictCursor 似乎在 psycopg2 下不起作用

发布于 2024-11-24 09:08:05 字数 732 浏览 4 评论 0原文

我以前没有使用过 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。

I haven't worked with psycopg2 before but I'm trying to change the cursor factory to DictCursor so that fetchall or fetchone will return a dictionary instead of a list.

I created a test script to make things simple and only test this functionality. Here's my little bit of code that I feel should work

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

The res variable is always a list and not a dictionary as I would expect.

A current workaround that I've implemented is to use this function that builds a dictionary and run each row returned by fetchall through it.

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

Python is version 2.6.7 and psycopg2 is version 2.4.2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

晒暮凉 2024-12-01 09:08:07
res = cur.fetchall()

使 res 成为 psycopg2.extras.DictRow 的列表。


或者,您可以利用 cur 是可迭代的这一事实,而不是调用 cur.fetchall

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

因此您将能够使用 访问数据类似于 dict 的语法。

res = cur.fetchall()

makes res a list of psycopg2.extras.DictRows.


Alternatively, instead of calling cur.fetchall you can take advantage of the fact that cur is an iterable:

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

and thus you'll be able to access the data with dict-like syntax.

一抹微笑 2024-12-01 09:08:07

另一种解决方案是使用 命名元组游标,因为 Real Dict 游标将破坏任何使用整数索引的查询,如其文档中所述。

使用命名元组游标,您可以使用点语法访问它们,如下所示:

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

这使事情保持整洁,并且据我所知不会破坏任何内容。

Another solution would be to use the Named Tuple Cursor since the Real Dict Cursor will break any query that uses integer indicies as explained in its documentation.

With Named Tuple Cursors, you can access them with dot syntax like so:

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

This keeps things tidy and won't break anything as far as I know.

情绪 2024-12-01 09:08:07

虽然这是一个较老的问题,但它仍然出现在谷歌中,所以我想我会为来自大G的其他人添加我的代码。

对我来说,我有多行,我想返回到字典中并且理想情况下,不想使用循环或类似的方式从数据库中的字段设置键。

因此,使用 dict 理解语法我​​可以执行以下操作。

表行插入字典


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....希望这对一些人有帮助。

While this is an older question, it still comes up in google so i thought i would add my code to this for anyone else coming from the big G.

For me, i have multiple rows that i would like to return back into a dictionary and ideally dont want to use a loop or similar to set the key from a field in the database..

So using dict comprehension syntax i can do the following.

Table Rows Into Dictionary


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

Function & Calling 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;")

While this is using a for x in y loop, its pythonic as far as i can tell....Hopefully this will be of help to some out there.

柠檬色的秋千 2024-12-01 09:08:07

除了使用 RealDictCursor 功能外,您可能还需要询问所有列
(在选择后使用 * 符号),如答案中所做的那样。

我对结果的某些列不感兴趣,因为它们具有已知的值
已在 WHERE 条件中使用。但是 SELECT (..., ..., ..., ...) FROM ... WHERE ...
变体没有给我字典。

此致 !
哈雷

In addition to use RealDictCursor feature, you may also have to ask for all columns
(using the * symbol after select), as is done in the answer.

I was not interested in some columns of the result, since they had known values
already used in WHERE conditions. But the SELECT (..., ..., ..., ...) FROM ... WHERE ...
variant didn't give me dictionaries.

Best regards !
Harley

凉城已无爱 2024-12-01 09:08:07

因此,要使其像 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]

该代码使用 fetchall() 使其格式与 MySQL 版本的字典游标相同。不知道为什么他们以不同的方式实现它,但这将帮助您获得实际 python 字典的相同输出,而不是 fetchall() 情况下的列表。

So to make this work like the mysql version of the Dictionary cursor you will have to wrap it in another function or code. I will go on the forums and suggest this to them for future deployments of their code to return a dictionary when the fetchall() call is used with the Dictionary Cursor. Here is some sample code you can use to fix for it:

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]

This code makes it the same format as the MySQL version of the dictionary cursor using fetchall(). Not sure why they implemented it differently, but this will help you get the same output of an actual python dictionary rather than a list in the fetchall() case.

本王不退位尔等都是臣 2024-12-01 09:08:06

使用 RealDictCursor

import psycopg2.extras

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

这给你一个列表,其中的行是真正的 python 字典,而不是“高级 psycopg2 列表”。

Use RealDictCursor:

import psycopg2.extras

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

This gives you a list with rows as real python dictionaries instead of "advanced psycopg2 list".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文