diff options
Diffstat (limited to 'odoo/models.py')
| -rw-r--r-- | odoo/models.py | 96 |
1 files changed, 56 insertions, 40 deletions
diff --git a/odoo/models.py b/odoo/models.py index 2086c137a61..3fdcaaf573e 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -651,8 +651,22 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): :param fields: list of lists of fields to traverse :return: list of lists of corresponding values """ + import_compatible = self.env.context.get('import_compat', True) lines = [] - for record in self: + + def splittor(rs): + """ Splits the self recordset in batches of 1000 (to avoid + entire-recordset-prefetch-effects) & removes the previous batch + from the cache after it's been iterated in full + """ + for idx in range(0, len(rs), 1000): + sub = rs[idx: idx+1000] + for rec in sub: + yield rec + rs.invalidate_cache(ids=sub.ids) + + # memory stable but ends up prefetching 275 fields (???) + for idx, record in enumerate(splittor(self)): # main line of record, initially empty current = [''] * len(fields) lines.append(current) @@ -684,8 +698,9 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): else: primary_done.append(name) - # This is a special case, its strange behavior is intended! - if field.type == 'many2many' and len(path) > 1 and path[1] == 'id': + # in import_compat mode, m2m should always be exported as + # a comma-separated list of xids in a single cell + if import_compatible and field.type == 'many2many' and len(path) > 1 and path[1] == 'id': xml_ids = [r.__export_xml_id() for r in value] current[i] = ','.join(xml_ids) or False continue @@ -2833,47 +2848,48 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): raise UserError(_('Unable to delete this document because it is used as a default property')) # Delete the records' properties. - self.env['ir.property'].search([('res_id', 'in', refs)]).unlink() + with self.env.norecompute(): + self.env['ir.property'].search([('res_id', 'in', refs)]).unlink() - self.check_access_rule('unlink') + self.check_access_rule('unlink') - cr = self._cr - Data = self.env['ir.model.data'].sudo().with_context({}) - Defaults = self.env['ir.default'].sudo() - Attachment = self.env['ir.attachment'] + cr = self._cr + Data = self.env['ir.model.data'].sudo().with_context({}) + Defaults = self.env['ir.default'].sudo() + Attachment = self.env['ir.attachment'] - for sub_ids in cr.split_for_in_conditions(self.ids): - query = "DELETE FROM %s WHERE id IN %%s" % self._table - cr.execute(query, (sub_ids,)) + for sub_ids in cr.split_for_in_conditions(self.ids): + query = "DELETE FROM %s WHERE id IN %%s" % self._table + cr.execute(query, (sub_ids,)) - # Removing the ir_model_data reference if the record being deleted - # is a record created by xml/csv file, as these are not connected - # with real database foreign keys, and would be dangling references. - # - # Note: the following steps are performed as superuser to avoid - # access rights restrictions, and with no context to avoid possible - # side-effects during admin calls. - data = Data.search([('model', '=', self._name), ('res_id', 'in', sub_ids)]) - if data: - data.unlink() - - # For the same reason, remove the defaults having some of the - # records as value - Defaults.discard_records(self.browse(sub_ids)) - - # For the same reason, remove the relevant records in ir_attachment - # (the search is performed with sql as the search method of - # ir_attachment is overridden to hide attachments of deleted - # records) - query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' - cr.execute(query, (self._name, sub_ids)) - attachments = Attachment.browse([row[0] for row in cr.fetchall()]) - if attachments: - attachments.unlink() - - # invalidate the *whole* cache, since the orm does not handle all - # changes made in the database, like cascading delete! - self.invalidate_cache() + # Removing the ir_model_data reference if the record being deleted + # is a record created by xml/csv file, as these are not connected + # with real database foreign keys, and would be dangling references. + # + # Note: the following steps are performed as superuser to avoid + # access rights restrictions, and with no context to avoid possible + # side-effects during admin calls. + data = Data.search([('model', '=', self._name), ('res_id', 'in', sub_ids)]) + if data: + data.unlink() + + # For the same reason, remove the defaults having some of the + # records as value + Defaults.discard_records(self.browse(sub_ids)) + + # For the same reason, remove the relevant records in ir_attachment + # (the search is performed with sql as the search method of + # ir_attachment is overridden to hide attachments of deleted + # records) + query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' + cr.execute(query, (self._name, sub_ids)) + attachments = Attachment.browse([row[0] for row in cr.fetchall()]) + if attachments: + attachments.unlink() + + # invalidate the *whole* cache, since the orm does not handle all + # changes made in the database, like cascading delete! + self.invalidate_cache() # recompute new-style fields if self.env.recompute and self._context.get('recompute', True): |
