From f4e7e2a6e2f5f1ff9f648f36db75b1722f62b59d Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Thu, 1 Feb 2024 09:45:00 +0000 Subject: [PATCH] [FIX] account_financial_report: optimize computation of analytic accounts Installing the module in a big DB was very slow. I applied several optimizations to the method for working better with big datasets: - Prefetch all analytic account distribution. - Batch writes as much as possible. @moduon MT-4982 --- .../models/account_move_line.py | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/account_financial_report/models/account_move_line.py b/account_financial_report/models/account_move_line.py index 7150239c..284ab52d 100644 --- a/account_financial_report/models/account_move_line.py +++ b/account_financial_report/models/account_move_line.py @@ -1,5 +1,7 @@ # Copyright 2019 ACSONE SA/NV () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).- +from collections import defaultdict + from odoo import api, fields, models @@ -12,24 +14,26 @@ class AccountMoveLine(models.Model): @api.depends("analytic_distribution") def _compute_analytic_account_ids(self): - for record in self: - if not record.analytic_distribution: - record.analytic_account_ids = False - else: - record.update( - { - "analytic_account_ids": [ - ( - 6, - 0, - self.env["account.analytic.account"] - .browse([int(k) for k in record.analytic_distribution]) - .exists() - .ids, - ) - ] - } - ) + # Prefetch all involved analytic accounts + with_distribution = self.filtered("analytic_distribution") + batch_by_analytic_account = defaultdict(list) + for record in with_distribution: + for account_id in map(int, record.analytic_distribution): + batch_by_analytic_account[account_id].append(record.id) + existing_account_ids = set( + self.env["account.analytic.account"] + .browse(map(int, batch_by_analytic_account)) + .exists() + .ids + ) + # Store them + self.analytic_account_ids = False + for account_id, record_ids in batch_by_analytic_account.items(): + if account_id not in existing_account_ids: + continue + self.browse(record_ids).analytic_account_ids = [ + fields.Command.link(account_id) + ] def init(self): """