DictCursor似乎不适用于psycopg2

Jim*_*Jim 54 python postgresql dictionary psycopg2

我之前没有使用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
Run Code Online (Sandbox Code Playgroud)

res变量总是一个列表,而不是我期望的字典.

我实现的当前解决方法是使用此函数来构建字典并运行fetchall通过它返回的每一行.

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

Python是版本2.6.7,psycopg2是版本2.4.2.

ker*_*rma 98

使用RealDictCursor:

cur = conn.cursor(cursor_factory = psycopg2.extras.RealDictCursor)
cur.execute("SELECT * from review")
res = cur.fetchall()    
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个列表,其中行为真正的python词典,而不是"高级psycopg2列表".

  • 要解决`AttributeError:模块'psycopg2'没有属性'extras',请执行import psycopg2.extras` (7认同)
  • 是的,这有效.. 在 Bottle-plugin https://github.com/raisoblast/bottle-pgsql/issues/2 中作为错误归档 (2认同)

unu*_*tbu 31

res = cur.fetchall()
Run Code Online (Sandbox Code Playgroud)

使得res列表psycopg2.extras.DictRow秒.


或者,不是调用cur.fetchall你可以利用cur可迭代的事实:

cur.execute("SELECT * from review")
for row in cur:
    print(row['column_name'])
Run Code Online (Sandbox Code Playgroud)

因此,您将能够使用dict类似语法访问数据.

  • @Seth:如果你想要一个真正的字典,请使用名为`RealDictCursor`的名字. (20认同)
  • 如以下指定的@kerma,可以使用[RealDictCursor](http://initd.org/psycopg/docs/extras.html#real-dictionary-cursor)。可选地,通过dict像这样强制转换行,可以达到相同的效果:`dict_cur =(cur(row)for cur in row)`@Seth:docs声明提供RealDictCursor:_请注意,此游标非常专业,不允许使用正常访问(使用整数索引)以获取数据。如果您需要同时访问数据库行作为字典和列表,请使用通用DictCursor而不是RealDictCursor。_ (2认同)

Bri*_*eau 9

另一个解决方案是使用命名元组游标,因为Real Dict Cursor将破坏任何使用整数指示的查询,如文档中所述.

使用Named Tuple Cursors,您可以使用点语法访问它们,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

据我所知,这可以保持整洁,不会破坏任何东西.


Ang*_* 84 5

虽然这是一个较旧的问题,但它仍然出现在谷歌中,所以我想我会为来自大 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}
Run Code Online (Sandbox Code Playgroud)

函数和调用它

#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;")
Run Code Online (Sandbox Code Playgroud)

虽然这是在 y 循环中使用 for x ,但据我所知,它是 pythonic ......希望这对那里的一些人有所帮助。