changeset 05235e67b280 in trytond:default details: https://hg.tryton.org/trytond?cmd=changeset&node=05235e67b280 description: Use global cache for Function fields in readonly transactions
issue10491 review352081002 diffstat: CHANGELOG | 1 + trytond/model/modelsql.py | 17 ++++++++++++++--- trytond/model/modelstorage.py | 14 ++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diffs (93 lines): diff -r f04093042cc4 -r 05235e67b280 CHANGELOG --- a/CHANGELOG Mon Oct 11 11:38:37 2021 +0200 +++ b/CHANGELOG Mon Oct 11 11:52:42 2021 +0200 @@ -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 diff -r f04093042cc4 -r 05235e67b280 trytond/model/modelsql.py --- a/trytond/model/modelsql.py Mon Oct 11 11:38:37 2021 +0200 +++ b/trytond/model/modelsql.py Mon Oct 11 11:52:42 2021 +0200 @@ -835,8 +835,8 @@ 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 @@ 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 diff -r f04093042cc4 -r 05235e67b280 trytond/model/modelstorage.py --- a/trytond/model/modelstorage.py Mon Oct 11 11:38:37 2021 +0200 +++ b/trytond/model/modelstorage.py Mon Oct 11 11:52:42 2021 +0200 @@ -1515,7 +1515,10 @@ 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 @@ 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 @@ 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 @@ 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})