Use global cache for Function fields in readonly transactions

issue10491
review352081002
This commit is contained in:
Nicolas Évrard committed 2021-10-11 11:52:42 +02:00
1 parent 870981c561
commit b3786087a9
3 files changed
+25 -7

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Use global cache for Function fields in readonly transactions
* Add format method to DictSchemaMixin
* Allow modify record name on the reports
* Add methods to format number and symbol on Lang
+14 -3
View File
@@ -835,8 +835,8 @@ class ModelSQL(ModelStorage):
getter_fields = [f for f in all_fields
if f in cls._fields and hasattr(cls._fields[f], 'get')]
cache = transaction.get_cache()[cls.__name__]
if getter_fields and cachable_fields:
cache = transaction.get_cache()[cls.__name__]
for row in result:
for fname in cachable_fields:
cache[row['id']][fname] = row[fname]
@@ -879,13 +879,24 @@ class ModelSQL(ModelStorage):
for sub_results in grouped_slice(
result, record_cache_size(transaction)):
sub_results = list(sub_results)
sub_ids = [r['id'] for r in sub_results]
sub_ids = []
for row in sub_results:
if (row['id'] not in cache
or any(f not in cache[row['id']]
for f in field_list)):
sub_ids.append(row['id'])
else:
for fname in field_list:
row[fname] = cache[row['id']][fname]
getter_results = field.get(
sub_ids, cls, field_list, values=sub_results)
for fname in field_list:
getter_result = getter_results[fname]
for row in sub_results:
row[fname] = getter_result[row['id']]
if row['id'] in sub_ids:
row[fname] = getter_result[row['id']]
if transaction.readonly:
cache[row['id']][fname] = row[fname]
def read_related(field, Target, rows, fields):
name = field.name
+10 -4
View File
@@ -1515,7 +1515,10 @@ class ModelStorage(Model):
raise AttributeError('"%s" has no attribute "%s"' % (self, name))
try:
if field._type not in ('many2one', 'reference'):
if field._type not in (
'many2one', 'reference',
'one2many', 'many2many', 'one2one',
):
# fill local cache for quicker access later
value \
= self._local_cache[self.id][name] \
@@ -1667,7 +1670,7 @@ class ModelStorage(Model):
self._transaction.set_user(self._user), \
self._transaction.reset_context(), \
self._transaction.set_context(
self._context, _check_access=False):
self._context, _check_access=False) as transaction:
if (self.id in self._cache and name in self._cache[self.id]
and not require_context_field):
# Use values from cache
@@ -1684,7 +1687,9 @@ class ModelStorage(Model):
read_data = self.read(list(index.keys()), list(ffields.keys()))
read_data.sort(key=lambda r: index[r['id']])
# create browse records for 'remote' models
no_local_cache = {'one2one', 'one2many', 'many2many', 'binary'}
no_local_cache = {'binary'}
if not transaction.readonly:
no_local_cache |= {'one2one', 'one2many', 'many2many'}
for data in read_data:
id_ = data['id']
to_delete = set()
@@ -1705,7 +1710,8 @@ class ModelStorage(Model):
if (field._type in no_local_cache
or field.context
or getattr(field, 'datetime_field', None)
or isinstance(field, fields.Function)):
or (isinstance(field, fields.Function)
and not transaction.readonly)):
to_delete.add(fname)
self._cache[id_]._update(
**{k: v for k, v in data.items() if k not in to_delete})