summaryrefslogtreecommitdiff
path: root/odoo/fields.py
diff options
context:
space:
mode:
authorAdrian Torres <adt@odoo.com>2020-07-16 08:59:43 +0000
committerRaphael Collet <rco@odoo.com>2020-07-16 11:09:05 +0000
commit9fefa0874502b820752d4b323a80e5015e211803 (patch)
tree454dd3765fd6cd1b1dbf7329c14e428e17ec7a36 /odoo/fields.py
parent65b8751e32a1792184953a4fd4fab48048613a60 (diff)
[FIX] core: mapped() does not prefetch as expected
Before this commit, calling `mapped()` on a relational field of a single record inside a for loop does not correctly propagate the prefetch ids from the bigger recordset down to the record inside the loop: [rec.line_ids.mapped('name') for rec in recs] To be more precise, `recs` correctly propagates prefetching information down to `rec.line_ids`, but method `mapped()` does not pass it along to the record that triggers the prefetching. This resulted in one query per record in `recs`, so if `recs` were a 1000 records recordset, at least 1000 queries would be necessary. With this commit, the `mapped()` function correctly propagates the `_prefetch_ids` of the larger recordset (`rec.line_ids`) so that the prefetching works properly and the 1000 queries are brought down to 1. This commit is a followup on #42611. closes odoo/odoo#54565 X-original-commit: 0e97053fee36c0c76b70cb94be5340c3144b178b Signed-off-by: Raphael Collet (rco) <rco@openerp.com> Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
Diffstat (limited to 'odoo/fields.py')
-rw-r--r--odoo/fields.py8
1 files changed, 6 insertions, 2 deletions
diff --git a/odoo/fields.py b/odoo/fields.py
index 6ad32a505b6..31d67bc6556 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -1018,8 +1018,12 @@ class Field(MetaField('DummyField', (object,), {})):
# retrieve values in cache, and fetch missing ones
vals = records.env.cache.get_until_miss(records, self)
while len(vals) < len(records):
- # trigger prefetching on remaining records, and continue retrieval
- remaining = records[len(vals):]
+ # It is important to construct a 'remaining' recordset with the
+ # _prefetch_ids of the original recordset, in order to prefetch as
+ # many records as possible. If not done this way, scenarios such as
+ # [rec.line_ids.mapped('name') for rec in recs] would generate one
+ # query per record in `recs`!
+ remaining = records._browse(records.env, records[len(vals):]._ids, records._prefetch_ids)
self.__get__(first(remaining), type(remaining))
vals += records.env.cache.get_until_miss(remaining, self)