[IMP] avoid one query when recomputing a field (#18846)

Specifically, instead of reading fields on `recs.exists()`, simply read those
fields and catch `MissingError`.  This generates around 5% less queries.
This commit is contained in:
Raphael Collet
2017-08-16 16:55:09 +02:00
committed by GitHub
parent a2a37fe9c4
commit 8b49007a32
4 changed files with 22 additions and 5 deletions
+1 -1
View File
@@ -665,7 +665,7 @@ class Message(models.Model):
# Calculate remaining ids: if not void, raise an error
other_ids = other_ids.difference(set(document_related_ids))
if not other_ids:
if not (other_ids and self.browse(other_ids).exists()):
return
raise AccessError(
_('The requested operation cannot be completed due to security restrictions. Please contact your system administrator.\n\n(Document type: %s, Operation: %s)') %
+1 -1
View File
@@ -356,7 +356,7 @@ class ComputeRecursive(models.Model):
_name = 'test_new_api.recursive'
name = fields.Char(required=True)
parent = fields.Many2one('test_new_api.recursive')
parent = fields.Many2one('test_new_api.recursive', ondelete='cascade')
display_name = fields.Char(compute='_compute_display_name', store=True)
@api.depends('name', 'parent.display_name')
@@ -202,6 +202,11 @@ class TestFields(common.TransactionCase):
self.assertEqual(c.display_name, 'X / C')
self.assertEqual(d.display_name, 'X / C / D')
# delete b; both c and d are deleted in cascade; c should also be marked
# to recompute, but recomputation should not fail...
b.unlink()
self.assertEqual((a + b + c + d).exists(), a)
def test_12_cascade(self):
""" test computed field depending on computed field """
message = self.env.ref('test_new_api.message_0_0')
+15 -3
View File
@@ -3024,6 +3024,8 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
@api.multi
def _write(self, vals):
# low-level implementation of write()
if not self:
return True
self.check_field_access_rights('write', list(vals))
cr = self._cr
@@ -4781,13 +4783,23 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
ns = [f.name for f in fs if f.store]
# evaluate fields, and group record ids by update
updates = defaultdict(set)
for rec in recs.exists():
vals = rec._convert_to_write({n: rec[n] for n in ns})
for rec in recs:
try:
vals = {n: rec[n] for n in ns}
except MissingError:
continue
vals = rec._convert_to_write(vals)
updates[frozendict(vals)].add(rec.id)
# update records in batch when possible
with recs.env.norecompute():
for vals, ids in pycompat.items(updates):
recs.browse(ids)._write(dict(vals))
target = recs.browse(ids)
try:
target._write(dict(vals))
except MissingError:
# retry without missing records
target.exists()._write(dict(vals))
# mark computed fields as done
for f in fs:
recs._recompute_done(f)