设置cursor_factory无效果:PostgreSQL查询返回元组而非字典
问题分析与解决
你遇到的问题核心是**cursor_factory参数的传递方式错误**,导致psycopg2没有应用RealDictCursor,所以默认返回了tuple类型的结果。
为什么会这样?
看你创建连接的代码:
self.con = psycopg2.connect("host={h} dbname={n} user={u} password={p}".format( h=self.host, n=self.name, u=self.username, p=self.pwd, cursor_factory=RealDictCursor))
你把cursor_factory=RealDictCursor作为format()的参数,但实际上这个参数根本没被嵌入到连接字符串里——而且更关键的是:cursor_factory是psycopg2.connect()的关键字参数,不是连接URL字符串的一部分。
连接字符串里只包含主机、数据库名、用户、密码这类连接属性,而游标工厂需要直接作为参数传给connect()方法,否则psycopg2会忽略它,使用默认的普通游标(返回tuple)。
修正后的代码
修改你的_create_connection方法,把cursor_factory作为关键字参数传递给connect():
def _create_connection(self): if self.con is None or self.con.closed: self.con = psycopg2.connect( host=self.host, dbname=self.name, user=self.username, password=self.pwd, cursor_factory=RealDictCursor )
这样psycopg2就会正确使用RealDictCursor,查询结果会返回字典列表。
额外的小建议
- 你在每个游标上下文管理器的
finally里都直接关闭了连接,这意味着每次查询后连接都会被断开,下次查询又要重新建立连接。如果你的应用查询频率较高,这样会带来不必要的性能开销,可以考虑保持连接复用(比如只在连接确实断开时重新创建)。 - 在异常处理中,你
yield Exception()的方式不太符合上下文管理器的规范,通常应该直接raise异常让调用方处理,而不是返回一个Exception对象,这样调用方可以更清晰地捕获和处理数据库错误。
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

