From: Raphael Collet Date: Tue, 9 Sep 2014 13:23:52 +0000 (+0200) Subject: [FIX] openerp/osv/fields: disable prefetching when reading inverse of one2many fields X-Git-Tag: 8.0.0~106 X-Git-Url: http://git.inspyration.org/?a=commitdiff_plain;h=742846400423484a1a752ea13f7fb8bf84ed4712;p=odoo%2Fodoo.git [FIX] openerp/osv/fields: disable prefetching when reading inverse of one2many fields This fixes issue #2146. The inverse of a one2many field can be an inherited field (_inherits). In that case, we cannot read its value with a simple database query. Instead, we let the related field read it, but for performance considerations we disable the prefetching of other fields. --- diff --git a/openerp/models.py b/openerp/models.py index ef5c2bb..79a61a7 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -3155,6 +3155,9 @@ class BaseModel(object): elif self.env.field_todo(field): # field must be recomputed, do not prefetch records to recompute records -= self.env.field_todo(field) + elif not self._context.get('prefetch_fields', True): + # do not prefetch other fields + pass elif self._columns[field.name]._prefetch: # here we can optimize: prefetch all classic and many2one fields fnames = set(fname diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index f11ef97..37fe2b1 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -671,29 +671,20 @@ class one2many(_column): context = dict(context or {}) context.update(self._context) + # retrieve the records in the comodel 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)] - 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 + result = {id: [] for id in ids} + # read the inverse of records without prefetching other fields on them + for record in records.with_context(prefetch_fields=False): + # record[inverse] may be a record or an integer + result[int(record[inverse])].append(record.id) + + return result def set(self, cr, obj, id, field, values, user=None, context=None): result = []