【问题标题】:psycopg2: DictCursor vs RealDictCursorpsycopg2:DictCursor 与 RealDictCursor
【发布时间】:2018-01-06 01:11:18
【问题描述】:

AFAIU 和文档中,RealDictCursor 是一个专门的 DictCursor,它只允许从键(又名列名)访问列,而 DictCursor 允许从键或索引号访问数据。
我想知道如果 DictCursor 提供更大的灵活性,为什么要实施 RealDictCursor?性能方面(或内存方面)是否如此不同(我想支持 RealDictCursor ......)?
换句话说,RealDictCursor 用例与 DictCursor 分别是什么?

【问题讨论】:

  • 事实上它们并不像文档描述的那样相似:访问是相似的,但是如果你 json.dumps(your_request),DictCursor 不会显示键,RealDictCursor 会显示它们。
  • 我假设如果您的查询返回大量行,那么每行的真实字典将是一个巨大的开销,因为它存储的是每行上的每个值的键(列名),而不是的常规元组,它具有较小的内存占用。我个人认为命名变量和命名数据库列比假设数据库表中的列的顺序和数量永远不会改变,并且总是尝试使用名称而不是索引序数更可取。 dictcursor 似乎介于两者之间,通过单独存储索引到列名映射来节省每行空间。

标签: python python-3.x postgresql psycopg2


【解决方案1】:

类 psycopg2.extras.RealDictCursor(*args, **kwargs)

使用真正的字典作为行的基本类型的游标。请注意,此游标非常专业,不允许正常访问(使用整数索引)来获取数据。如果您需要以字典和列表的形式访问数据库行,请使用通用 DictCursor 而不是 RealDictCursor。 class psycopg2.extras.RealDictConnection 自动使用 RealDictCursor 的连接。

注意 自 Psycopg2.5 以来不是很有用:您可以使用 psycopg2.connect(dsn, cursor_factory=RealDictCursor) 代替 RealDictConnection。班级 psycopg2.extras.RealDictRow(cursor) 表示一个 dict 子类 数据记录。


【讨论】:

  • 这是来自initd.org/psycopg/docs/extras.html 站点的定义。它实际上让我质疑使用 RealDictCursor 与使用似乎建议的 dictcursor 作为默认值。我认为此页面上的注释具有误导性,因为它说它非常专业。在大多数情况下,在将响应转换为带有标头的表或 csv 时,返回的查询需要标头。
【解决方案2】:

真正的字典游标的主要优点是很容易将查询输出为json。

比较:

with psycopg2.connect('dbname=test') as connection:
    with connection.cursor(cursor_factory=RealDictCursor) as cursor:
        cursor.execute("select * from my_table")
        print(json.dumps(cursor.fetchall()))

with psycopg2.connect('dbname=test') as connection:
    with connection.cursor() as cursor:
        cursor.execute("select * from my_table")
        columns = [desc[0] for desc in cursor.description]
        real_dict = [dict(zip(columns, row)) for row in cursor.fetchall()]
        print(json.dumps(real_dict))

在性能方面,这些选项之间没有重要区别。

对于常规或类似字典的游标,您无法使用 json.dumps(cursor.fetchall()) 获得预期的 json,并且需要上面显示的转换。另一方面,真正的字典光标会产生更大的结果,因此如果您真的不需要它,则不应使用它。

【讨论】:

  • 这不是像问题所要求的那样比较 DictCursor 和 RealDictCursor
  • @stenci - 添加了解释。
  • RealDictCursor 对于需要标题行的表格和 csv 也很有帮助。
  • 感谢您的回答。想知道为什么我的输出结构像元组列表,以及如何获取 JSON/dict 数据。
  • 我无法将其中一个字段设为 json 类型,它返回的是字符串类型
猜你喜欢
  • 2014-10-05
  • 2011-10-08
  • 2014-05-11
  • 2013-08-14
  • 2013-01-30
  • 2022-01-21
  • 1970-01-01
  • 2014-06-02
相关资源
最近更新 更多