diff options
| author | Ivan Yelizariev <iel@odoo.com> | 2021-01-28 16:14:41 +0000 |
|---|---|---|
| committer | Raphael Collet <rco@odoo.com> | 2021-02-02 15:18:41 +0000 |
| commit | d66652b4aa514546356306e3eb48eaecaba07c33 (patch) | |
| tree | 0bc86672ef4a828be3e7ca7989ed4c537aef5e79 /odoo/fields.py | |
| parent | 7840b21483c0012174e6028a39b114ce56f06158 (diff) | |
[FIX] core: initialize new stored related field via SQL
Filling the new column in SQL is dramatically faster than doing it via
the ORM, which iterates over all the records in the table.
The test case is creating a related field for 100+ records with distinct
values. Setting the field's value was taking more than 100 queries. It
now takes 3 queries.
task-2449313
opw-2380445
opw-2389376
https://github.com/odoo/enterprise/pull/15910
closes odoo/odoo#65421
X-original-commit: 82644c3ea20f7b5748f92ce4d0f4585335995d29
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Diffstat (limited to 'odoo/fields.py')
| -rw-r--r-- | odoo/fields.py | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/odoo/fields.py b/odoo/fields.py index 8e940a3a387..b936d6c83fd 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -809,6 +809,21 @@ class Field(MetaField('DummyField', (object,), {})): self.update_db_column(model, column) self.update_db_notnull(model, column) + # optimization for computing simple related fields like 'foo_id.bar' + if ( + not column + and len(self.related or ()) == 2 + and self.related_field.store and not self.related_field.compute + ): + join_field = model._fields[self.related[0]] + if ( + join_field.type == 'many2one' + and join_field.store and not join_field.compute + ): + model.pool.post_init(self.update_db_related, model) + # discard the "classical" computation + return False + return not column def update_db_column(self, model, column): @@ -859,6 +874,22 @@ class Field(MetaField('DummyField', (object,), {})): elif not self.required and has_notnull: sql.drop_not_null(model._cr, model._table, self.name) + def update_db_related(self, model): + """ Compute a stored related field directly in SQL. """ + comodel = model.env[self.related_field.model_name] + model.env.cr.execute(""" + UPDATE "{model_table}" AS x + SET "{model_field}" = y."{comodel_field}" + FROM "{comodel_table}" AS y + WHERE x."{join_field}" = y.id + """.format( + model_table=model._table, + model_field=self.name, + comodel_table=comodel._table, + comodel_field=self.related[1], + join_field=self.related[0], + )) + ############################################################################ # # Alternatively stored fields: if fields don't have a `column_type` (not |
