From e8822809224037855a8715cf9779d0b7f63c6e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Wed, 10 Apr 2024 12:44:54 -0300 Subject: [PATCH] [FIX] chunked: explicitly flush on every iteration Fixes #362 --- openupgradelib/openupgrade.py | 8 +----- openupgradelib/openupgrade_tools.py | 41 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/openupgradelib/openupgrade.py b/openupgradelib/openupgrade.py index cae812e7..38abd8b1 100644 --- a/openupgradelib/openupgrade.py +++ b/openupgradelib/openupgrade.py @@ -3261,17 +3261,11 @@ def chunked(records, single=True): """Memory and performance friendly method to iterate over a potentially large number of records. Yields either a whole chunk or a single record at the time. Don't nest calls to this method.""" - if version_info[0] > 10: - invalidate = records.env.cache.invalidate - elif version_info[0] > 7: - invalidate = records.env.invalidate_all - else: - raise Exception("Not supported Odoo version for this method.") size = core.models.PREFETCH_MAX model = records._name ids = records.with_context(prefetch_fields=False).ids for i in range(0, len(ids), size): - invalidate() + openupgrade_tools.invalidate_cache(records.env, flush=True) chunk = records.env[model].browse(ids[i : i + size]) if single: for record in chunk: diff --git a/openupgradelib/openupgrade_tools.py b/openupgradelib/openupgrade_tools.py index 8840bc03..4ce080fe 100644 --- a/openupgradelib/openupgrade_tools.py +++ b/openupgradelib/openupgrade_tools.py @@ -26,6 +26,8 @@ from lxml.etree import tostring from lxml.html import fromstring +logger = logging.getLogger(__name__) + def table_exists(cr, table): """Check whether a certain table or view exists""" @@ -348,3 +350,42 @@ def replace_html_replacement_attr_shortcut(attr_rp="", **kwargs): } ) return kwargs + + +def invalidate_cache(env, flush=True): + """Version-independent cache invalidation. + + :param flush: whether pending updates should be flushed before invalidation. + It is ``True`` by default, which ensures cache consistency. + Do not use this parameter unless you know what you are doing. + """ + + # It needs to be loaded after odoo is imported + from .openupgrade import version_info + + version = version_info[0] + + # Warning on possibly untested versions where chunked might not work as expected + if version > 17: # unreleased version at this time + logger.warning( + f"openupgradelib.invalidate_cache hasn't been tested on Odoo {version}. " + "Please report any issue you may find and consider bumping this warning " + "to the next version otherwise." + ) + + # 16.0: invalidate_all is re-introduced (with flush_all) + if version >= 16: + env.invalidate_all(flush=flush) + # 13.0: the write cache and flush is introduced + elif version >= 13: + if flush: + env["base"].flush() + env.cache.invalidate() + # 11.0: the invalidate_all method is deprecated + elif version >= 11: + env.cache.invalidate() + # 8.0: new api + elif version >= 8: + env.invalidate_all() + else: + raise Exception("Not supported Odoo version for this method.")