# HG changeset patch # User Sylvain Thénault # Date 1443521344 -7200 # Node ID 57c60a96de706c36eaed9c7babdb50d80d25d370 # Parent c43e5dc41f8bd9062f00875dd8872fa3d18dabbd [migration] fix change_attribute_type to update the live schema Closes #7170830 diff -r c43e5dc41f8b -r 57c60a96de70 server/migractions.py --- a/server/migractions.py Fri Jul 24 09:57:08 2015 +0200 +++ b/server/migractions.py Tue Sep 29 12:09:04 2015 +0200 @@ -1477,19 +1477,28 @@ * the actual schema won't be updated until next startup """ rschema = self.repo.schema.rschema(attr) - oldtype = rschema.objects(etype)[0] - rdefeid = rschema.rdef(etype, oldtype).eid - allownull = rschema.rdef(etype, oldtype).cardinality[0] != '1' + oldschema = rschema.objects(etype)[0] + rdef = rschema.rdef(etype, oldschema) sql = ("UPDATE cw_CWAttribute " "SET cw_to_entity=(SELECT cw_eid FROM cw_CWEType WHERE cw_name='%s')" - "WHERE cw_eid=%s") % (newtype, rdefeid) + "WHERE cw_eid=%s") % (newtype, rdef.eid) self.sqlexec(sql, ask_confirm=False) dbhelper = self.repo.system_source.dbhelper sqltype = dbhelper.TYPE_MAPPING[newtype] cursor = self.cnx.cnxset.cu - dbhelper.change_col_type(cursor, 'cw_%s' % etype, 'cw_%s' % attr, sqltype, allownull) + allownull = rdef.cardinality[0] != '1' + dbhelper.change_col_type(cursor, 'cw_%s' % etype, 'cw_%s' % attr, sqltype, allownull) if commit: self.commit() + # manually update live schema + eschema = self.repo.schema[etype] + rschema._subj_schemas[eschema].remove(oldschema) + rschema._obj_schemas[oldschema].remove(eschema) + newschema = self.repo.schema[newtype] + rschema._update(eschema, newschema) + rdef.object = newschema + del rschema.rdefs[(eschema, oldschema)] + rschema.rdefs[(eschema, newschema)] = rdef def cmd_add_entity_type_table(self, etype, commit=True): """low level method to create the sql table for an existing entity. diff -r c43e5dc41f8b -r 57c60a96de70 server/test/data-migractions/migratedapp/schema.py --- a/server/test/data-migractions/migratedapp/schema.py Fri Jul 24 09:57:08 2015 +0200 +++ b/server/test/data-migractions/migratedapp/schema.py Tue Sep 29 12:09:04 2015 +0200 @@ -19,7 +19,7 @@ import datetime as dt from yams.buildobjs import (EntityType, RelationType, RelationDefinition, SubjectRelation, Bytes, - RichString, String, Int, Boolean, Datetime, Date) + RichString, String, Int, Boolean, Datetime, Date, Float) from yams.constraints import SizeConstraint, UniqueConstraint from cubicweb.schema import (WorkflowableEntityType, RQLConstraint, RQLVocabularyConstraint, @@ -49,7 +49,7 @@ } nom = String(maxsize=64, fulltextindexed=True) web = String(maxsize=128) - tel = Int() + tel = Float() fax = Int() rncs = String(maxsize=128) ad1 = String(maxsize=128) diff -r c43e5dc41f8b -r 57c60a96de70 server/test/unittest_migractions.py --- a/server/test/unittest_migractions.py Fri Jul 24 09:57:08 2015 +0200 +++ b/server/test/unittest_migractions.py Tue Sep 29 12:09:04 2015 +0200 @@ -704,6 +704,18 @@ mh.cmd_add_relation_type('same_as') self.assertTrue(self.table_sql(mh, 'same_as_relation')) + def test_change_attribute_type(self): + with self.mh() as (cnx, mh): + mh.cmd_create_entity('Societe', tel=1) + mh.commit() + mh.change_attribute_type('Societe', 'tel', 'Float') + self.assertNotIn(('Societe', 'Int'), self.schema['tel'].rdefs) + self.assertIn(('Societe', 'Float'), self.schema['tel'].rdefs) + self.assertEqual(self.schema['tel'].rdefs[('Societe', 'Float')].object, 'Float') + tel = mh.rqlexec('Any T WHERE X tel T')[0][0] + self.assertEqual(tel, 1.0) + self.assertIsInstance(tel, float) + class MigrationCommandsComputedTC(MigrationTC): """ Unit tests for computed relations and attributes