浅谈 Odoo 的 @ormcache
装饰器。
1. 缓存的背景
在实际开发中,某些计算可能会消耗大量时间和资源。例如,在计算字段的值时,可能需要执行复杂的逻辑或查询大量数据。为了避免在相同参数下重复执行这些耗时的计算,我们可以使用缓存机制。
2. 使用 @ormcache 装饰器
在 Odoo 中,@ormcache
装饰器是一个强大的工具,它可以应用在方法上,用于缓存方法的结果。通过将它与计算字段结合使用,我们可以实现对计算结果的高效缓存。在修改的方法中清除缓存,保证数据的统一性,下次访问的时候就会从orm里面重新读取
3. 示例代码
以下是一个简单的示例代码,演示了如何在 Odoo 中使用 @ormcache
装饰器结合计算字段:
# my_ormcache_test.py
import time
from odoo import models, api
from odoo.tools import ormcache
class ResPartner(models.Model):
_inherit = 'res.partner'
def write(self, vals):
self.clear_cache()
return super(ResPartner, self).write(vals)
@api.model
@ormcache('partner_name')
def compute_something(self, partner_name):
# 模拟耗时操作
time.sleep(5)
print('从ORM中读取------')
return f"{partner_name}"
def button_compute(self):
print('从缓存中中读取------')
ret = self.compute_something(self.name)
def clear_cache(self):
self.compute_something.clear_cache(self)
odoo界面截图
在这个例子中,我们定义了一个计算字段 compute_something
,并通过 @ormcache
装饰器告诉 Odoo 对这个方法的结果进行缓存。在 button_compute
方法中演示了从缓存中读取数据,而不重新计算。
4. 源码剖析
def lookup(self, method, *args, **kwargs):
d, key0, counter = self.lru(args[0])
key = key0 + self.key(*args, **kwargs)
try:
r = d[key]
counter.hit += 1
return r
except KeyError:
counter.miss += 1
value = d[key] = self.method(*args, **kwargs)
return value
except TypeError:
_logger.warning("cache lookup error on %r", key, exc_info=True)
counter.err += 1
return self.method(*args, **kwargs)
self.lru(args[0])
返回了一个字典d
、一个缓存键的基础部分key0
以及一个计数器counter
。这里假设args[0]
是用于生成缓存键的参数。key = key0 + self.key(*args, **kwargs)
通过将基础部分和方法的参数计算得到最终的缓存键key
。- 接下来,尝试从字典
d
中获取缓存结果:
- 如果成功命中缓存,则返回缓存的值,并增加计数器的命中次数。
- 如果在缓存中未找到,捕获
KeyError
异常,表示缓存未命中,增加计数器的未命中次数。然后执行原始方法,并将结果存入缓存。
- 如果捕获到
TypeError
异常,表示在缓存查找过程中出现了错误。此时,增加计数器的错误次数,并执行原始方法。
总体而言,这段代码实现了缓存查找的逻辑,如果能够从缓存中找到结果就直接返回,否则执行原始方法,将结果存入缓存。异常处理部分确保即使在缓存查找的过程中出现错误,也能够执行原始方法以确保不影响程序的正常运行。
标签:缓存,ormcache,魔力,self,args,key,Odoo,compute From: https://blog.51cto.com/u_14480405/9219099