如何将Odoo自定义日志记录模型从回滚中排除



我正在Odoo中创建一个自定义日志模型。当然,我希望模型完全不受典型事务回滚行为的影响。当然,这样做的原因是,我不希望以后在代码中出现异常,导致永远不会添加日志条目。

下面是一个示例场景:

class SomeModel(models.Model):
def some_method(self):
self.env["my.custom.log"].add_entry("SomeModel.some_method started running")
...
raise Exception("Something went wrong...")

在这种情况下,我想在我的自定义日志中创建一个条目,用信号通知该方法开始运行。但是,根据代码后面的逻辑,可能会引发异常。如果出现异常,Odoo当然会回滚数据库事务,这是为了防止错误的数据提交到数据库。

但是,如果出现异常,我不希望我的日志条目消失。像任何正常的日志一样,我希望我的my.custom.log模型不受Odoo典型的回滚行为的影响,无论以后发生什么,都能立即记录信息。

我知道我可以手动回滚或提交事务,但这对我没有真正的帮助。如果我只是在添加日志条目后运行env.cr.commit(),它肯定会添加日志条目,但它也会添加之前发生的所有其他操作。那肯定不好。在添加日志条目之前运行env.cr.rollback()也没有意义,因为即使以后没有发生异常,所有挂起的操作也会回滚。

我该如何解决此问题?如何使我的日志条目始终添加到数据库中,而不管代码中发生了什么?

注意:我知道Odoo有一个内置的日志。我有自己的理由想要创建自己的独立日志

我已经找到了一个解决方案,但我不知道这是否一定是最好的方法

在这个例子中,我现在确定的解决方案是定义add_entry()日志模型方法,如下所示:

# If log entries are created normally and an exception occurs, Odoo will rollback
# the current database transaction, meaning that along with other data, the log
# entries will not be created. With this method, log entries are created with a
# separate database cursor, independent of the current transaction.
def add_entry(self, message):
self.flush() # ADDED WITH IMPORTANT EDIT BELOW
with registry(self.env.cr.dbname).cursor() as cr:
record = self.with_env(self.env(cr)).create({"message": message})
return self.browse(record.id)
# Otherwise the method would look simply like this...
def add_entry(self, message):
return self.create({"message": message})

解释

  1. 我从delivery/models/delivery_carrier.py:212的Odoodelivery模块中得到了with registry(self.env.cr.dbname).cursor() as cr的想法。在那个文件中,奥多奥似乎正试图做我在这个问题上想要做的事情。

  2. 我从iap/models/iap.py:182的Odooiap模块中得到了self.with_env(self.env(cr))的想法。它比做self.env(cr)["my.custom.log"]更干净。

  3. 我不直接从create()方法返回新记录。我敢肯定,在游标即将关闭的环境中返回记录集是不对的(因为with语句(。相反,我只是挂起记录ID,然后在当前环境中获取记录,并使用self.browse()获取光标。希望这实际上是最好的方法,不会带来任何重大的性能问题。

如果您有任何改进建议,请随时参与!

重要编辑(一天后(

我在上面的代码中添加了self.flush()行,并进行了编辑。事实证明,由于某种原因,当with语句__exit__和单独的游标被提交时,当它试图刷新数据时可能会引发异常。

delivery/models/delivery_carrier.py:207上也做了同样的事情。我不确定为什么有必要,但看起来确实如此。我认为刷新数据也需要考虑一些性能因素,但我不确定它们是什么,现在看来它们是不可避免的。再说一遍,如果你知道什么,请权衡一下。

最新更新