[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:
parent
bfb29230b7
commit
7428464004
|
@ -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
|
||||
|
|
|
@ -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 = []
|
||||
|
|
Loading…
Reference in New Issue