python: 为什么在conn.autocommit(1)中SQLObject失败?
在我的服务器代码中,有一个调用 _SO_fetchAlternateID
的地方(这个调用嵌套在某个 value
调用里),最终会调用到 pgconnection.py
中的 makeConnection
。
这个调用在 conn.autocommit(1)
时失败了,错误信息是:
类型错误:'bool' 对象不可调用
这是 SQLObject(0.8.7)的代码:
def makeConnection(self):
try:
if self.use_dsn:
conn = self.module.connect(self.dsn)
else:
conn = self.module.connect(**self.dsn_dict)
except self.module.OperationalError, e:
raise self.module.OperationalError("%s; used connection string %r" % (e, self.dsn))
if self.autoCommit:
# psycopg2 does not have an autocommit method.
if hasattr(conn, 'autocommit'):
conn.autocommit(1)
return conn
调试显示,conn
确实持有一个连接对象,但 autocommit
不是一个方法,而是一个布尔值(False)。
self.module
是模块 'psycopg2'(2.4.2)。
这是不是配置问题?版本不匹配?
更新:
原因实际上是 psycopg2-2.4.2 中的一个不兼容问题。查看 C 源代码,发现 psycopg/connection.h 中有一个不幸命名为 autocommit
的整数变量。版本 2-2.4 的情况正常。
2 个回答
听起来在代码的某个地方,有人把 autocommit = True
这个设置给了 conn 对象。
当解释器运行到这段代码时:
conn.autocommit(1)
实际上,它会检查:
True(1)
检查一下 self.dsn 或 self.dsn_dict 的内容,如果里面没有 'autocommit' 这个布尔值的键。
你刚发现了一个错误。看看这段代码:
def _setAutoCommit(self, conn, auto):
# psycopg2 does not have an autocommit method.
if hasattr(conn, 'autocommit'):
conn.autocommit(auto)
这段代码假设 conn
(类型是 psycopg2.connection
)可能没有 autocommit
这个属性,但如果它有的话,应该是一个函数。这个假设在 psycopg2.connection
的上下文中是错误的,因为实际上 psycopg2.connection.autocommit
是一个布尔值。
在你提到的 makeConnection
函数中,也做了同样的假设,还有其他几个函数也是如此。
要修复这个问题,可以把每个像 conn.autocommit(val)
这样的调用改成 conn.autocommit = val
,这应该很简单,即使使用 sed
工具也能轻松做到。