diff --git a/unserialize_field/ir_model_fields.py b/unserialize_field/ir_model_fields.py
index ea5d25cf4..e57e21af4 100644
--- a/unserialize_field/ir_model_fields.py
+++ b/unserialize_field/ir_model_fields.py
@@ -19,22 +19,27 @@
# along with this program. If not, see .
#
##############################################################################
-from openerp.osv.orm import Model
-from openerp.osv import fields
+from openerp.osv import orm
+from openerp.tools.translate import _
-class ir_model_fields(Model):
+class ir_model_fields(orm.Model):
_inherit = 'ir.model.fields'
def action_unserialize_field(self, cr, uid, ids, context=None):
step = 1000
offset = 0
+ # Prevent _auto_init to commit the transaction
+ # before the data is migrated safely
+ commit_org = cr.commit
+ cr.commit = lambda *args: None
+
for this in self.browse(cr, uid, ids, context=context):
pool_obj = self.pool.get(this.model_id.model)
- needs_write = self.create_database_column(
- cr, uid, pool_obj, this.name)
- while needs_write:
+ self.create_database_column(cr, uid, pool_obj, this.name,
+ context=context)
+ while True:
ids = pool_obj.search(
cr, uid,
[(this.serialization_field_id.name, '!=', '{}')],
@@ -48,62 +53,66 @@ class ir_model_fields(Model):
this.serialization_field_id.name,
this.name, context=context)
offset += 1
+
+ cr.commit = commit_org
return True
- def create_database_column(self, cr, uid, pool_obj, field_name):
- needs_write = True
- old = pool_obj._columns[field_name]
- field_declaration_args = []
- field_declaration_kwargs = dict(
- manual=old.manual,
- string=old.string,
- required=old.required,
- readonly=old.readonly,
- domain=old._domain,
- context=old._context,
- states=old.states,
- priority=old.priority,
- change_default=old.change_default,
- size=old.size,
- ondelete=old.ondelete,
- translate=old.translate,
- select=old.select,
- )
-
- if old._type == 'many2one':
- field_declaration_args = [old._obj]
- elif old._type == 'selection':
- field_declaration_args = [old.selection]
- elif old._type == 'one2many':
- field_declaration_args = [old._obj, old._fields_id]
- field_declaration_kwargs['limit'] = old._limit
- needs_write = False
- elif old._type == 'many2many':
- field_declaration_args = [old._obj]
- field_declaration_kwargs['rel'] = old._rel
- field_declaration_kwargs['id1'] = old._id1
- field_declaration_kwargs['id2'] = old._id2
- field_declaration_kwargs['limit'] = old._limit
- needs_write = False
+ def create_database_column(self, cr, uid, pool_obj, field_name,
+ context=None):
+ field_obj = self.pool.get('ir.model.fields')
+ field_ids = field_obj.search(
+ cr, uid, [
+ ('name', '=', field_name),
+ ('model', '=', pool_obj._name),
+ ], context=context)
- field_declaration = getattr(fields, old._type)(
- *field_declaration_args,
- **field_declaration_kwargs)
+ old = pool_obj._columns[field_name]
+ if not old.manual:
+ orm.except_orm(
+ _('Error'),
+ _('This operation can only be performed on manual fields'))
+ if old._type == 'many2many':
+ # Cross table name length of manually created many2many
+ # fields can easily become too large. Although it would
+ # probably work if the table name length was within bounds,
+ # this scenario has not been tested because of this limitation.
+ raise orm.except_orm(
+ _("Error"),
+ _("Many2many fields are not supported. See "
+ "https://bugs.launchpad.net/openobject-server/+bug/1174078 "
+ "for more information"))
+ if old._type == 'one2many':
+ # How to get a safe field name for the relation field
+ # on the target model?
+ raise orm.except_orm(
+ _("Error"),
+ _("One2many fields are not handled yet"))
+
+ # ORM prohibits to change the 'storing system' of the field
+ cr.execute("""
+ UPDATE ir_model_fields
+ SET serialization_field_id = NULL
+ WHERE id = %s""" % (field_ids[0],))
- pool_obj._columns[field_name] = field_declaration
+ del pool_obj._columns[field_name]
+ pool_obj.__init__(self.pool, cr)
pool_obj._auto_init(cr, {'update_custom_fields': True})
- return needs_write
def unserialize_field(self, cr, uid, pool_obj, read_record,
serialization_field_name, field_name,
context=None):
- if not field_name in read_record[serialization_field_name]:
+ serialized_values = read_record[serialization_field_name]
+ if not field_name in serialized_values:
return False
+
+ value = serialized_values.pop(field_name)
+ if pool_obj._columns[field_name]._type in ('many2many', 'one2many'):
+ value = [(6, 0, value)]
+
pool_obj.write(
cr, uid, read_record['id'],
{
- field_name:
- read_record[serialization_field_name][field_name],
+ field_name: value,
+ serialization_field_name: serialized_values,
},
context=context)
- return True
diff --git a/unserialize_field/ir_model_fields.xml b/unserialize_field/ir_model_fields.xml
index 17f6701bb..4a92c4d39 100644
--- a/unserialize_field/ir_model_fields.xml
+++ b/unserialize_field/ir_model_fields.xml
@@ -16,5 +16,21 @@
+
+
+ form
+ ir.model
+
+
+
+
+
+
+
+
+