diff options
| author | Raphael Collet <rco@odoo.com> | 2020-04-02 06:45:54 +0000 |
|---|---|---|
| committer | Raphael Collet <rco@odoo.com> | 2020-04-03 11:40:29 +0000 |
| commit | 9afce4805fc8bac45fdba817488aa867fddff69b (patch) | |
| tree | 665f109f3f9881b7e2e0d56caf1a7d9e5aaf9219 /addons/base_sparse_field/models/models.py | |
| parent | 6eb7d5c6a07f678e1d1adca7137652e0626ea17e (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.py | 59 |
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) |
