[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.
This commit is contained in:
Raphael Collet 2014-09-09 15:23:52 +02:00
parent bfb29230b7
commit 7428464004
2 changed files with 10 additions and 16 deletions

View File

@ -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

View File

@ -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)
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 res
return result
def set(self, cr, obj, id, field, values, user=None, context=None):
result = []