cursor_factory=None 引发异常
我把我的 psycopg2
连接封装在一个叫 DB
的类里,其中有一个方法是用来获取游标的。我还在这个方法的参数里加了一个 cursor_factory
,但是当我把默认值设为 None
时,就出现了错误。
class DB:
... connection code and other stuff ...
def fetchcursor(self, query, params, in_cursor_factory=None):
cur = self.conn.cursor(cursor_factory=in_cursor_factory)
cur.execute(query, params)
return cur
db = DB()
db.fetchcursor("SELECT * FROM foo", None)
我遇到的错误是:
TypeError: 'NoneType' object is not callable
当我把 None
换成 psycopg2.extras.DictCursor
时就没问题了。我想把默认值设为 None
,正如文档中所说的那样:
cursor(name=None, cursor_factory=None, scrollable=None, withhold=False)
1 个回答
1
确实,看起来 connection.cursor()
的实现 在处理 cursor_factory
参数设置为 None
时表现得不太好。
这段代码没有检查 factory
是否被设置为 Py_None
,而是直接调用了它。如果没有提供这个关键字参数,就会使用 connection.cursor_factory
,根据源代码,这个默认值是 extensions.cursor
(比如 psycopg2._psycopg.cursor
)。
你可以通过测试是否为 None
来复现这个问题,并在这种情况下使用 connection.cursor_factory
:
def fetchcursor(self, query, params, in_cursor_factory=None):
if in_cursor_factory is None:
in_cursor_factory = self.conn.cursor_factory
cur = self.conn.cursor(cursor_factory=in_cursor_factory)
cur.execute(query, params)
return cur
这假设你使用的是 psycopg
版本 2.5 或更新的版本;connection.cursor_factory
是在这个版本中新增的。
对于之前的版本,只需使用 psycopg2._psycopg.cursor
来替代 self.conn.cursor_factory
。