避免 OpenERP 审计跟踪错误

发布于 2024-09-17 16:50:44 字数 987 浏览 6 评论 0 原文

我想通过安装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 新手,我不知道如何克服这个问题?
有什么提示可以克服这个问题吗?
感谢

I'd like to manage OpenERP user's activity by installing the audittrail module.
After creating some rules ( define which user, which object and which activity (create, update..) will be monitored). I update a product to see it works.
When I've tried to update a product i got the system error. Seeing the log, I get
[2010-08-31 12:53:35,042] Cursor not closed explicitly
[2010-08-31 12:53:35,043] Cursor was created at /home/pilgrim/working/sources/addons/audittrail/audittrail.py:204

Here the line that causes error
cr = pooler.get_db(db).cursor()
Looking at sql_db.py, I get the comment

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()

Since I'm new to Python, I don't know how to overcome this issue?
Any hint to get over this?
Thank

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

遇见了你 2024-09-24 16:50:44

查看源代码以了解正在发生的事情非常重要。
但从您发布的内容来看,前一个光标似乎没有明确关闭。

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

我建议您破解audittrail.py以找到您在哪里创建光标以及在哪里关闭它们。一个典型的问题是异常处理不正确,导致代码跳过正常关闭。

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

t would be important to see the source code to understand whats going on.
But from what you have posted it looks like the previous cursor was not closed explicitly.

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

I would suggest that you hack audittrail.py to find where ever you are creating the cursor and where ever you close them. A typical issue arises in incorrect handling of exceptions, causing code to jump over normal closure.

Try placing a try, except and finally clause around the questionable cursor operation. That should help you to get around the problem.

无悔心 2024-09-24 16:50:44

我想我找到了答案。
看例子

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

call a()

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:是的,我们应该尝试一下……最后

I think I find the answer.
See an example

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

call a()

before return 
in finally
1

It's normal. OK.
Try another example ( code extract from 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()

Seeing that the implementation of do_something_with_db trying to open the cursor ( can be called connection) but the current one is not explicitly closed.
So the solution is simple: Pass the current cr around

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

Now the error's gone.

@Don Kirkby: Yes, we should experiment with try...finally

生死何惧 2024-09-24 16:50:44

您可以在调试器中运行 OpenERP,例如 PyDev 插件 .org/" rel="nofollow noreferrer">Eclipse?我发现这是追踪问题的最有效方法。我没有使用审计跟踪模块,但我快速浏览了 源代码,并且光标似乎在 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 语句以确保光标始终关闭。以下是上面的示例在转换后的外观:

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()

Can you run OpenERP in a debugger like the PyDev plug in for Eclipse? I find that the most effective way to track down problems. I haven't used the audit trail module, but I took a quick look at the source code, and it appears that the cursor is being opened near the beginning of log_fct(). (I would have expected it to report line 207, which version are you running?) Here's what I think is the relevant code:

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()

It looks like there are several return statements in the method, but each one seems to call cr.close() first, so I don't see any obvious problems. Try running it in the debugger with a break point in this method. If that's not possible, you can try writing to the log with something like this:

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

Update:
You commented that this happens under heavy load. Perhaps an exception is being thrown and the cursor is not being closed. You could use a try ... finally statement to make sure that the cursor is always closed. Here's how the sample above would look after converting it:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文