summaryrefslogtreecommitdiff
path: root/odoo/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'odoo/models.py')
-rw-r--r--odoo/models.py96
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):