避免OpenERP audittrail错误

时间:2010-08-31 06:05:26

标签: python audit-trail openerp

我想通过安装audittrail模块来管理OpenERP用户的活动 创建一些规则(定义哪个用户,哪个对象以及将监视哪个活动(创建,更新...))。我更新了一个产品,看它是否有效 当我尝试更新产品时,我遇到了系统错误。看到日志,我得到了 [2010-08-31 12:53:35,042]光标未明确关闭
[2010-08-31 12:53:35,043]光标创建于/home/pilgrim/working/sources/addons/audittrail/audittrail.py:204

这里导致错误的行
          cr = pooler.get_db(db)。cursor()
看一下sql_db.py,我收到了评论

def __del__(self):
    if not self.__closed:
        # Oops. 'self' has not been closed explicitly.
        # The cursor will be deleted by the garbage collector,
        # but the database connection is not put back into the connection
        # pool, preventing some operation on the database like dropping it.
        # This can also lead to a server overload.
        msg = "Cursor not closed explicitly\n"  \
              "Cursor was created at %s:%s" % self.__caller
        log(msg, netsvc.LOG_WARNING)
        self.close()

由于我是Python的新手,我不知道如何克服这个问题? 有什么暗示可以克服这个问题吗? 感谢

3 个答案:

答案 0 :(得分:4)

看到源代码来了解最新情况是非常重要的。 但是根据你发布的内容,看起来前一个光标没有明确关闭。

cr = sqldb.db_connect(dbname).cursor()
.........
cr.close()
cr = None

我建议您破解audittrail.py以查找创建光标的位置以及关闭它们的位置。一个典型的问题是异常处理错误,导致代码跳过正常的闭包。

尝试在可疑的游标操作周围放置一个try,except和finally子句。这应该可以帮助你解决问题。

答案 1 :(得分:2)

我想我找到了答案。 查看示例

def a():  
  try:
    print 'before return '
    return 1
  finally:
    print 'in finally'

拨打()

before return 
in finally
1

这很正常。好。 尝试另一个例子(来自audittrail.py的代码提取)

def do_something_with_db(db):
   // open cusror again
   cr = db.cursor()
   // do somethign
   // close cursor internally
   cr.close()
def execute(db)
   // 1, open connection and open cursor
   cr = db.cursor
   try:
        //2, do something with db, seeing that this method will open cursor again
       return do_something_with_db(db)
   finally:
       cr.close()

看到do_something_with_db的实现尝试打开游标(可以称为连接),但当前的一个没有显式关闭。 所以解决方案很简单:将当前的cr传递给

Before
**do_something_with_db(db)**
after
**do_something_with_db(cr)**

现在错误消失了。

@Don Kirkby:是的,我们应该尝试尝试......终于

答案 2 :(得分:1)

您可以在PyDev plug inEclipse之类的调试器中运行OpenERP吗?我发现追踪问题的最有效方法。我没有使用审计跟踪模块,但是我快速查看了source code,看来光标正在log_fct()的开头附近打开。 (我原以为它会报告第207行,你正在运行哪个版本?)以下是我认为的相关代码:

def log_fct(self, db, uid, passwd, object, method, fct_src, *args):
    logged_uids = []
    pool = pooler.get_pool(db)
    cr = pooler.get_db(db).cursor() # line 207 in version 5.0.12

    # ...

    if method in ('create'):

        # ...

        cr.close()
        return res_id

    # ...

    cr.close()

看起来方法中有几个return语句,但是每个语句似乎都先调用cr.close(),所以我没有看到任何明显的问题。尝试在此方法中使用断点在调试器中运行它。如果这不可能,您可以尝试使用以下内容写入日志:

    logger = netsvc.Logger()
    logger.notifyChannel('audittrail', netsvc.LOG_INFO, 'something happened')

<强>更新 你评论说这是在重负荷下发生的。可能抛出异常并且光标未被关闭。您可以使用try ... finally statement来确保光标始终关闭。以下是转换后上面示例的样子:

def log_fct(self, db, uid, passwd, object, method, fct_src, *args):
    logged_uids = []
    pool = pooler.get_pool(db)
    cr = pooler.get_db(db).cursor() # line 207 in version 5.0.12
    try:

        # ...

        if method in ('create'):

            # ...

            return res_id

        # ...

    finally:
        cr.close()