From 4a1029582390164a74cf3594662dc61d8562aedf Mon Sep 17 00:00:00 2001 From: Martin Trigaux <mat@openerp.com> Date: Mon, 1 Sep 2014 16:28:56 +0200 Subject: [PATCH] [FIX] fields: avoid prefetching of one2many fields When reading a one2many field, the inverse mapping of the lines (matching m2o -> lines of corresponding record) was instantiating each line and then triggering the prefect of fields. To improve the performances, the inverse mapping is done in sql to avoid triggering the prefetching. --- openerp/osv/fields.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 76aaadfc2db6..f27b737a6b99 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -671,17 +671,27 @@ class one2many(_column): context = dict(context or {}) context.update(self._context) - res = dict((id, []) for id in ids) - comodel = obj.pool[self._obj].browse(cr, user, [], context) inverse = self._fields_id domain = self._domain(obj) if callable(self._domain) else self._domain domain = domain + [(inverse, 'in', ids)] - for record in comodel.search(domain, limit=self._limit): - # Note: record[inverse] can be a record or an integer! - assert int(record[inverse]) in res - res[int(record[inverse])].append(record.id) + records = comodel.search(domain, limit=self._limit) + record_ids = map(int, records) + + res = dict((id, []) for id in ids) + if record_ids: + cr.execute('SELECT id, %(inverse)s \ + FROM %(rel)s \ + WHERE id in %%s ' % { + 'inverse': inverse, + 'rel': comodel._table, + }, (tuple(record_ids),)) + record_value_id = dict(cr.fetchall()) + # match the result per id, preserving the order + for record in records: + key = record_value_id[record.id] + res[key].append(record.id) return res -- GitLab