首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分段故障扩展psycopg2._psycopg.cursor

分段故障扩展psycopg2._psycopg.cursor
EN

Stack Overflow用户
提问于 2014-02-25 23:50:51
回答 4查看 875关注 0票数 0

这一小段代码导致了SIGSEGV (我认为这在像python这样的垃圾收集语言中是不可能的,但我已经习惯了创建新类型的but的王牌)即使数据库已经存在,连接也可以工作,不管怎样,我试图扩展psycopg2._psycopg.cursor类,让一个函数以字典的形式返回查询结果,我做错了什么?

代码语言:javascript
复制
import psycopg2

class dcursor(psycopg2._psycopg.cursor):
    def __init__(self,parent_cursor):
        self=parent_cursor
    def dictfetchall(self): 
        "Returns all rows from a cursor as a dict" 
        desc = cursor.description 
        return [
                dict(zip([col[0] for col in desc], row)) 
                for row in cursor.fetchall() 
        ]

conn = psycopg2.connect("dbname=dbpgs user=openerp")
cur = dcursor(conn.cursor())
cur.execute('select name_related from hr_employee;')
print cur.dictfetchall()
EN

回答 4

Stack Overflow用户

发布于 2014-02-26 03:24:22

游标签名将连接作为第一个参数。您重写__init__的方式使其带有光标。Segfault随后出现。与其说你的类是一个游标,不如说它是一个包装器。您也没有调用__init__基类,并且self=parent_cursor什么也不做。

以你的例子为例,对游标进行子类化的正确方法如下:

代码语言:javascript
复制
class dcursor(psycopg2.extensions.cursor):
    def dictfetchall(self): 
        "Returns all rows from a cursor as a dict" 
        desc = self.description 
        return [
                dict(zip([col[0] for col in desc], row)) 
                for row in self.fetchall() 
        ]

conn = psycopg2.connect("dbname=dbpgs user=openerp")
cur = conn.cursor(cursor_factory=dcursor)
cur.execute('select name_related from hr_employee;')
print cur.dictfetchall()

但也请参阅fog关于使用DictCursor的建议。

票数 1
EN

Stack Overflow用户

发布于 2014-02-26 00:02:03

这是可能的,因为psycopg2是一个用C编写的模块,它只向Python公开它的应用程序接口。你可以在这里看到代码:http://github.com/psycopg/psycopg2.git

我猜你所遇到的是一个在心理手术中的bug。也就是说,_psycopg包名称中的下划线表明,在那里定义的类并不是真正的子类化。

为什么不把dictfetchall()定义为一个独立的助手函数呢?它不会访问cursor对象的任何内部状态,也不需要将其作为cursor方法。

票数 0
EN

Stack Overflow用户

发布于 2014-02-26 00:59:43

psycopg2是用C编写的,除非您知道自己在做什么,否则在调用/扩展模块时可能会导致SIGSEGV。所有常见的函数和方法都会仔细检查它们的参数,以避免破坏和安全问题,但现在,在某些领域,做正确的事情的重担落在了客户端代码身上。您只是碰到了其中的一个区域:扩展连接或游标类型。

要正确执行此操作,您需要在__init__方法中执行一些特定的工作,如下所示:

https://github.com/psycopg/psycopg2/blob/master/lib/extras.py#L49

具体地说,cursor (和connection)是新风格的类,需要使用super()和传递给__init__的完整参数列表进行初始化。至少:

代码语言:javascript
复制
def __init__(self, *args, **kwargs):
    super(DictCursorBase, self).__init__(*args, **kwargs)

我特别链接了这个示例,因为它已经完成了您需要的操作,即获取数据并将其作为dict提供。只需import psycopg.extras.DictCursor (使用dict-like row类)或import psycopg.extras.RealDictCursor (为每一行使用真正的dict ),您就完成了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22019341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档