python: 为什么在conn.autocommit(1)中SQLObject失败?

5 投票
2 回答
2512 浏览
提问于 2025-04-16 19:42

在我的服务器代码中,有一个调用 _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 个回答

1

听起来在代码的某个地方,有人把 autocommit = True 这个设置给了 conn 对象。

当解释器运行到这段代码时:

 conn.autocommit(1) 

实际上,它会检查:

 True(1) 

检查一下 self.dsn 或 self.dsn_dict 的内容,如果里面没有 'autocommit' 这个布尔值的键。

5

你刚发现了一个错误。看看这段代码:

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 工具也能轻松做到。

撰写回答