其他分享
首页 > 其他分享> > 【转载】odoo技术开发白皮书 第五部分 第十三章 Cache

【转载】odoo技术开发白皮书 第五部分 第十三章 Cache

作者:互联网

转载:http://book.odoomommy.com/chapter5/README13.html

第十三章 Cache

Cache的数据结构

Cache的数据结构是这样的一个字典:

{
    field: {
        record_id: value
    },
    field: {
        context_key:{
            record_id: value
        }
    }
}

Cache在初始化时会初始化一个_data的默认字典的字典属性, 用来存储缓存. 然后定义了一系列的方法来读取或者存储缓存.

Cache对象对外公开的主要几个方法有:

存储字段和计算字段的读取逻辑

odoo为了读取的效率考虑,引入缓存的机制。我们知道odoo中的字段大概分为存储非存储两类,在read方法中,对此做了区分,所有的存储字段和有依赖字段的计算字段的读取操作都将从数据库中读取并更新,而没有依赖的计算字段将直接从缓存中读取。

def read(self, fields=None, load='_classic_read'):
    """ read([fields])

    Reads the requested fields for the records in ``self``, low-level/RPC
    method. In Python code, prefer :meth:`~.browse`.

    :param fields: list of field names to return (default is all fields)
    :return: a list of dictionaries mapping field names to their values,
                with one dictionary per record
    :raise AccessError: if user has no read rights on some of the given
            records
    """
    fields = self.check_field_access_rights('read', fields)

    # fetch stored fields from the database to the cache
    stored_fields = set()
    for name in fields:
        field = self._fields.get(name)
        if not field:
            raise ValueError("Invalid field %r on model %r" % (name, self._name))
        if field.store:
            stored_fields.add(name)
        elif field.compute:
            # optimization: prefetch direct field dependencies
            for dotname in self.pool.field_depends[field]:
                f = self._fields[dotname.split('.')[0]]
                if f.prefetch and (not f.groups or self.user_has_groups(f.groups)):
                    stored_fields.add(f.name)
    self._read(stored_fields)

    return self._read_format(fnames=fields, load=load)

_read方法用来读取存储字段,_read_format方法用来从缓存中读取字段的值。字段本身的读取逻辑也有涉及到缓存的部分,请参考字段一章。

事务

事务(Transcation)是odoo15.0新引入的中间组件对象, 用来管理ORM的数据结构和事务.

事务主要有如下几个重要的属性:

然后有如下几个方法

flush

def flush(self):
    """ Flush pending computations and updates in the transaction. """
    env_to_flush = None
    for env in self.envs:
        if isinstance(env.uid, int) or env.uid is None:
            env_to_flush = env
            if env.uid is not None:
                break
    if env_to_flush is not None:
        env_to_flush['base'].flush()

flush方法的作用是将挂起的计算生效并更新到事务中.

clear

def clear(self):
    """ Clear the caches and pending computations and updates in the translations. """
    self.cache.invalidate()
    self.tocompute.clear()
    self.towrite.clear()

clear方法主要作用是设置缓存无效, 并清空要重新计算和重写的逻辑.

reset

def reset(self):
    """ Reset the transaction.  This clears the transaction, and reassigns
        the registry on all its environments.  This operation is strongly
        recommended after reloading the registry.
    """
    self.registry = Registry(self.registry.db_name)
    for env in self.envs:
        env.registry = self.registry
        lazy_property.reset_all(env)
    self.clear()

reset方法的作用是重置事务, 具体地说, 就是重新实例化注册中心, 并将环境变量中的注册中心重新加载. 最后调用clear方法 清空缓存和计算逻辑.

 

标签:缓存,fields,self,Cache,白皮书,field,字段,env,odoo
来源: https://blog.csdn.net/run_noob_vip/article/details/122805191