diff options
| author | Xavier Morel <xmo@odoo.com> | 2020-06-18 13:22:23 +0000 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2020-07-27 06:32:59 +0000 |
| commit | ef709fd92b7b22a58e60715c9ff7ab4476a83ca5 (patch) | |
| tree | 6216bc42fe21c6b37c2ebf5cc0d66b4ccade2fc1 /odoo/models.py | |
| parent | dfda8b010ba8f20ea4fbc730eebd9c23d163c85a (diff) | |
[IMP] core, base: avoid multiple xids when importing records w/ inherits
Before this change, we create an xid for every parent of a record
being imported, regardless of whether it already has an xid, or if
it's being created implicitly through the child.
This generates unnecessary extra xids on pre-existing objects
e.g. update 5 product variants -> the product gets 5 new xids despite
already having one.
We should *only* set a xid on parent records which are being
implicitly created by the creation of a child with a specified
xid. That is, we should never set a xid on the parent if it exists
before the child is created.
Update _process_end to try and see if "non-loaded" xids correspond to
an automatically generated "parent" xid: we're still setting a xid on
implicitly created records (if the child is created with a xid) so
they're properly removed if e.g. the module is uninstalled, but
because we're only doing so at creation these xids will not be visited
during update and _process_end will try to delete them.
A special case can be added to check that "unknown" parent xids don't
have children which _inherit them, in which case we want to protect them.
Task 2251039
closes odoo/odoo#53283
Related: odoo/enterprise#12023
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Diffstat (limited to 'odoo/models.py')
| -rw-r--r-- | odoo/models.py | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/odoo/models.py b/odoo/models.py index a5371e03327..cf0cbf4c7c3 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -1047,7 +1047,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): for id, xid, record, info in converted: if xid: xid = xid if '.' in xid else "%s.%s" % (current_module, xid) - batch_xml_ids.update(ModelData._generate_xmlids(xid, self)) + batch_xml_ids.add(xid) elif id: record['id'] = id batch.append((xid, record, info)) @@ -4063,6 +4063,7 @@ Fields: # determine which records to create and update to_create = [] # list of data to_update = [] # list of data + imd_data_list = [] # list of data for _update_xmlids() for data in data_list: xml_id = data.get('xml_id') @@ -4080,11 +4081,11 @@ Fields: continue d_id, d_module, d_name, d_model, d_res_id, d_noupdate, r_id = row record = self.browse(d_res_id) - if update and d_noupdate: + if r_id: data['record'] = record - elif r_id: - data['record'] = record - to_update.append(data) + imd_data_list.append(data) + if not (update and d_noupdate): + to_update.append(data) else: imd.browse(d_id).unlink() to_create.append(data) @@ -4093,22 +4094,6 @@ Fields: for data in to_update: data['record']._load_records_write(data['values']) - # determine existing parents for new records - for parent_model, parent_field in self._inherits.items(): - suffix = '_' + parent_model.replace('.', '_') - xml_ids_vals = { - (data['xml_id'] + suffix): data['values'] - for data in to_create - if data.get('xml_id') - } - for row in imd._lookup_xmlids(xml_ids_vals, self.env[parent_model]): - d_id, d_module, d_name, d_model, d_res_id, d_noupdate, r_id = row - if r_id: - xml_id = '%s.%s' % (d_module, d_name) - xml_ids_vals[xml_id][parent_field] = r_id - else: - imd.browse(d_id).unlink() - # check for records to create with an XMLID from another module module = self.env.context.get('install_module') if module: @@ -4121,9 +4106,18 @@ Fields: records = self._load_records_create([data['values'] for data in to_create]) for data, record in zip(to_create, records): data['record'] = record + if data.get('xml_id'): + # add XML ids for parent records that have just been created + for parent_model, parent_field in self._inherits.items(): + if not data['values'].get(parent_field): + imd_data_list.append({ + 'xml_id': f"{data['xml_id']}_{parent_model.replace('.', '_')}", + 'record': record[parent_field], + 'noupdate': data.get('noupdate', False), + }) + imd_data_list.append(data) # create or update XMLIDs - imd_data_list = [data for data in data_list if data.get('xml_id')] imd._update_xmlids(imd_data_list, update) return original_self.concat(*(data['record'] for data in data_list)) |
