summaryrefslogtreecommitdiff
path: root/addons/base_sparse_field/models/models.py
diff options
context:
space:
mode:
authorRaphael Collet <rco@odoo.com>2020-04-02 06:45:54 +0000
committerRaphael Collet <rco@odoo.com>2020-04-03 11:40:29 +0000
commit9afce4805fc8bac45fdba817488aa867fddff69b (patch)
tree665f109f3f9881b7e2e0d56caf1a7d9e5aaf9219 /addons/base_sparse_field/models/models.py
parent6eb7d5c6a07f678e1d1adca7137652e0626ea17e (diff)
[IMP] core: reflect models, fields and selections in batch
This saves 4.5% of the total installation time. X-original-commit: 8519064dce975af542ccd30dc14c56b9bb36d07b
Diffstat (limited to 'addons/base_sparse_field/models/models.py')
-rw-r--r--addons/base_sparse_field/models/models.py59
1 files changed, 37 insertions, 22 deletions
diff --git a/addons/base_sparse_field/models/models.py b/addons/base_sparse_field/models/models.py
index 184cb32a10a..0f9a2deebf5 100644
--- a/addons/base_sparse_field/models/models.py
+++ b/addons/base_sparse_field/models/models.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
+from collections import defaultdict
+
from odoo import models, fields, api, _
from odoo.exceptions import UserError
@@ -29,32 +31,45 @@ class IrModelFields(models.Model):
return super(IrModelFields, self).write(vals)
- def _reflect_model(self, model):
- super(IrModelFields, self)._reflect_model(model)
+ def _reflect_fields(self, model_names):
+ super()._reflect_fields(model_names)
# set 'serialization_field_id' on sparse fields; it is done here to
# ensure that the serialized field is reflected already
cr = self._cr
- query = """ UPDATE ir_model_fields
- SET serialization_field_id=%s
- WHERE model=%s AND name=%s
- RETURNING id
- """
- fields_data = self._existing_field_data(model._name)
-
- for field in model._fields.values():
- ser_field_id = None
- if field.sparse:
- if field.sparse not in fields_data:
- msg = _("Serialization field `%s` not found for sparse field `%s`!")
- raise UserError(msg % (field.sparse, field.name))
- ser_field_id = fields_data[field.sparse]['id']
-
- if fields_data[field.name]['serialization_field_id'] != ser_field_id:
- cr.execute(query, (ser_field_id, model._name, field.name))
- record = self.browse(cr.fetchone())
- self.pool.post_init(record.modified, ['serialization_field_id'])
- self.clear_caches()
+
+ # retrieve existing values
+ query = """
+ SELECT model, name, id, serialization_field_id
+ FROM ir_model_fields
+ WHERE model IN %s
+ """
+ cr.execute(query, [tuple(model_names)])
+ existing = {row[:2]: row[2:] for row in cr.fetchall()}
+
+ # determine updates, grouped by value
+ updates = defaultdict(list)
+ for model_name in model_names:
+ for field_name, field in self.env[model_name]._fields.items():
+ field_id, current_value = existing[(model_name, field_name)]
+ try:
+ value = existing[(model_name, field.sparse)][0] if field.sparse else None
+ except KeyError:
+ msg = _("Serialization field %r not found for sparse field %s!")
+ raise UserError(msg % (field.sparse, field))
+ if current_value != value:
+ updates[value].append(field_id)
+
+ if not updates:
+ return
+
+ # update fields
+ query = "UPDATE ir_model_fields SET serialization_field_id=%s WHERE id IN %s"
+ for value, ids in updates.items():
+ cr.execute(query, [value, tuple(ids)])
+
+ records = self.browse(id_ for ids in updates.values() for id_ in ids)
+ self.pool.post_init(records.modified, ['serialization_field_id'])
def _instanciate_attrs(self, field_data):
attrs = super(IrModelFields, self)._instanciate_attrs(field_data)