Use two models in generated migrations. Test column addition and removal.
This commit is contained in:
parent
15f571d296
commit
a1968e7f7d
@ -42,14 +42,15 @@ class TestSchemaDiff(fixture.DB):
|
||||
|
||||
def assertDiff(isDiff, tablesMissingInDatabase, tablesMissingInModel, tablesWithDiff):
|
||||
diff = schemadiff.getDiffOfModelAgainstDatabase(self.meta, self.engine, excludeTables=['migrate_version'])
|
||||
eq_(bool(diff), isDiff)
|
||||
eq_(
|
||||
(diff.tables_missing_from_B,
|
||||
diff.tables_missing_from_A,
|
||||
diff.tables_different.keys()),
|
||||
diff.tables_different.keys(),
|
||||
bool(diff)),
|
||||
(tablesMissingInDatabase,
|
||||
tablesMissingInModel,
|
||||
tablesWithDiff)
|
||||
tablesWithDiff,
|
||||
isDiff)
|
||||
)
|
||||
|
||||
# Model is defined but database is empty.
|
||||
@ -64,8 +65,9 @@ class TestSchemaDiff(fixture.DB):
|
||||
if repr(String()) == 'String()':
|
||||
self.assertEqualsIgnoreWhitespace(decls, '''
|
||||
from migrate.changeset import schema
|
||||
meta = MetaData()
|
||||
tmp_schemadiff = Table('tmp_schemadiff', meta,
|
||||
pre_meta = MetaData()
|
||||
post_meta = MetaData()
|
||||
tmp_schemadiff = Table('tmp_schemadiff', post_meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('name', UnicodeText),
|
||||
Column('data', UnicodeText),
|
||||
@ -74,19 +76,14 @@ class TestSchemaDiff(fixture.DB):
|
||||
else:
|
||||
self.assertEqualsIgnoreWhitespace(decls, '''
|
||||
from migrate.changeset import schema
|
||||
meta = MetaData()
|
||||
tmp_schemadiff = Table('tmp_schemadiff', meta,
|
||||
pre_meta = MetaData()
|
||||
post_meta = MetaData()
|
||||
tmp_schemadiff = Table('tmp_schemadiff', post_meta,
|
||||
Column('id', Integer, primary_key=True, nullable=False),
|
||||
Column('name', UnicodeText(length=None)),
|
||||
Column('data', UnicodeText(length=None)),
|
||||
)
|
||||
''')
|
||||
self.assertEqualsIgnoreWhitespace(upgradeCommands,
|
||||
'''meta.bind = migrate_engine
|
||||
tmp_schemadiff.create()''')
|
||||
self.assertEqualsIgnoreWhitespace(downgradeCommands,
|
||||
'''meta.bind = migrate_engine
|
||||
tmp_schemadiff.drop()''')
|
||||
|
||||
# Create table in database, now model should match database.
|
||||
self._applyLatestModel()
|
||||
@ -111,12 +108,14 @@ class TestSchemaDiff(fixture.DB):
|
||||
else:
|
||||
dataId = result.last_inserted_ids()[0]
|
||||
|
||||
# Modify table in model (by removing it and adding it back to model) -- drop column data and add column data2.
|
||||
# Modify table in model (by removing it and adding it back to model)
|
||||
# Drop column data, add columns data2 and data3.
|
||||
self.meta.remove(self.table)
|
||||
self.table = Table(self.table_name,self.meta,
|
||||
Column('id',Integer(),primary_key=True),
|
||||
Column('name',UnicodeText(length=None)),
|
||||
Column('data2',Integer(),nullable=True),
|
||||
Column('data3',Integer(),nullable=True),
|
||||
)
|
||||
assertDiff(True, [], [], [self.table_name])
|
||||
|
||||
@ -124,6 +123,36 @@ class TestSchemaDiff(fixture.DB):
|
||||
self._applyLatestModel()
|
||||
assertDiff(False, [], [], [])
|
||||
|
||||
# Drop column data3, add data4
|
||||
self.meta.remove(self.table)
|
||||
self.table = Table(self.table_name,self.meta,
|
||||
Column('id',Integer(),primary_key=True),
|
||||
Column('name',UnicodeText(length=None)),
|
||||
Column('data2',Integer(),nullable=True),
|
||||
Column('data4',Float(),nullable=True),
|
||||
)
|
||||
assertDiff(True, [], [], [self.table_name])
|
||||
|
||||
diff = schemadiff.getDiffOfModelAgainstDatabase(
|
||||
self.meta, self.engine, excludeTables=['migrate_version'])
|
||||
decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff,self.engine).genB2AMigration(indent='')
|
||||
|
||||
# decls have changed since genBDefinition
|
||||
exec decls in locals()
|
||||
# migration commands expect a namespace containing migrate_engine
|
||||
migrate_engine = self.engine
|
||||
# run the migration up and down
|
||||
exec upgradeCommands in locals()
|
||||
assertDiff(False, [], [], [])
|
||||
|
||||
exec decls in locals()
|
||||
exec downgradeCommands in locals()
|
||||
assertDiff(True, [], [], [self.table_name])
|
||||
|
||||
exec decls in locals()
|
||||
exec upgradeCommands in locals()
|
||||
assertDiff(False, [], [], [])
|
||||
|
||||
if not self.engine.name == 'oracle':
|
||||
# Make sure data is still present.
|
||||
result = self.engine.execute(self.table.select(self.table.c.id==dataId))
|
||||
|
@ -158,8 +158,8 @@ def upgrade(migrate_engine):
|
||||
repository=self.repo_path,
|
||||
)
|
||||
|
||||
self.assertTrue('User.create()' in source_script)
|
||||
self.assertTrue('User.drop()' in source_script)
|
||||
self.assertTrue("['User'].create()" in source_script)
|
||||
self.assertTrue("['User'].drop()" in source_script)
|
||||
|
||||
@fixture.usedb()
|
||||
def test_make_update_script_for_equal_models(self):
|
||||
@ -196,9 +196,9 @@ def upgrade(migrate_engine):
|
||||
|
||||
self.assertTrue(0
|
||||
< source_script.find('upgrade')
|
||||
< source_script.find('User.create()')
|
||||
< source_script.find("['User'].create()")
|
||||
< source_script.find('downgrade')
|
||||
< source_script.find('User.drop()'))
|
||||
< source_script.find("['User'].drop()"))
|
||||
|
||||
def setup_model_params(self):
|
||||
self.script_path = self.tmp_py()
|
||||
|
@ -96,7 +96,7 @@ class ModelGenerator(object):
|
||||
else:
|
||||
return """Column(%(name)r, %(commonStuff)s)""" % data
|
||||
|
||||
def _getTableDefn(self, table):
|
||||
def _getTableDefn(self, table, metaName='meta'):
|
||||
out = []
|
||||
tableName = table.name
|
||||
if self.declarative:
|
||||
@ -107,8 +107,8 @@ class ModelGenerator(object):
|
||||
out.append(" %s" % self.column_repr(col))
|
||||
out.append('\n')
|
||||
else:
|
||||
out.append("%(table)s = Table('%(table)s', meta," %
|
||||
{'table': tableName})
|
||||
out.append("%(table)s = Table('%(table)s', %(meta)s," %
|
||||
{'table': tableName, 'meta': metaName})
|
||||
for col in table.columns:
|
||||
out.append(" %s," % self.column_repr(col))
|
||||
out.append(")\n")
|
||||
@ -151,46 +151,61 @@ class ModelGenerator(object):
|
||||
'''
|
||||
|
||||
decls = ['from migrate.changeset import schema',
|
||||
'meta = MetaData()']
|
||||
for table in self._get_tables(
|
||||
missingA=True,missingB=True,modified=True
|
||||
):
|
||||
decls.extend(self._getTableDefn(table))
|
||||
'pre_meta = MetaData()',
|
||||
'post_meta = MetaData()',
|
||||
]
|
||||
upgradeCommands = ['pre_meta.bind = migrate_engine',
|
||||
'post_meta.bind = migrate_engine']
|
||||
downgradeCommands = list(upgradeCommands)
|
||||
|
||||
upgradeCommands, downgradeCommands = [], []
|
||||
for tableName in self.diff.tables_missing_from_A:
|
||||
upgradeCommands.append("%(table)s.drop()" % {'table': tableName})
|
||||
downgradeCommands.append("%(table)s.create()" % \
|
||||
{'table': tableName})
|
||||
for tableName in self.diff.tables_missing_from_B:
|
||||
upgradeCommands.append("%(table)s.create()" % {'table': tableName})
|
||||
downgradeCommands.append("%(table)s.drop()" % {'table': tableName})
|
||||
for tn in self.diff.tables_missing_from_A:
|
||||
pre_table = self.diff.metadataB.tables[tn]
|
||||
decls.extend(self._getTableDefn(pre_table, metaName='pre_meta'))
|
||||
upgradeCommands.append(
|
||||
"pre_meta.tables[%(table)r].drop()" % {'table': tn})
|
||||
downgradeCommands.append(
|
||||
"pre_meta.tables[%(table)r].create()" % {'table': tn})
|
||||
|
||||
for tn in self.diff.tables_missing_from_B:
|
||||
post_table = self.diff.metadataA.tables[tn]
|
||||
decls.extend(self._getTableDefn(post_table, metaName='post_meta'))
|
||||
upgradeCommands.append(
|
||||
"post_meta.tables[%(table)r].create()" % {'table': tn})
|
||||
downgradeCommands.append(
|
||||
"post_meta.tables[%(table)r].drop()" % {'table': tn})
|
||||
|
||||
for (tn, td) in self.diff.tables_different.iteritems():
|
||||
if td.columns_missing_from_A or td.columns_different:
|
||||
pre_table = self.diff.metadataB.tables[tn]
|
||||
decls.extend(self._getTableDefn(
|
||||
pre_table, metaName='pre_meta'))
|
||||
if td.columns_missing_from_B or td.columns_different:
|
||||
post_table = self.diff.metadataA.tables[tn]
|
||||
decls.extend(self._getTableDefn(
|
||||
post_table, metaName='post_meta'))
|
||||
|
||||
for tableName in self.diff.tables_different:
|
||||
dbTable = self.diff.metadataB.tables[tableName]
|
||||
td = self.diff.tables_different[tableName]
|
||||
for col in td.columns_missing_from_A:
|
||||
upgradeCommands.append('%s.append_column(%s)' % (
|
||||
tableName,
|
||||
self.column_repr(
|
||||
self.diff.metadataB.tables[tableName].columns[col])))
|
||||
downgradeCommands.append('%s.columns[%r].drop()' % (tableName, col))
|
||||
upgradeCommands.append(
|
||||
'pre_meta.tables[%r].columns[%r].drop()' % (tn, col))
|
||||
downgradeCommands.append(
|
||||
'pre_meta.tables[%r].columns[%r].create()' % (tn, col))
|
||||
for col in td.columns_missing_from_B:
|
||||
upgradeCommands.append('%s.columns[%r].drop()' % (tableName, col))
|
||||
downgradeCommands.append('%s.columns[%r].create()' % (tableName, col))
|
||||
upgradeCommands.append(
|
||||
'post_meta.tables[%r].columns[%r].create()' % (tn, col))
|
||||
downgradeCommands.append(
|
||||
'post_meta.tables[%r].columns[%r].drop()' % (tn, col))
|
||||
for modelCol, databaseCol, modelDecl, databaseDecl in td.columns_different:
|
||||
upgradeCommands.append(
|
||||
'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
|
||||
tableName, modelCol.name, databaseCol.name))
|
||||
tn, modelCol.name, databaseCol.name))
|
||||
downgradeCommands.append(
|
||||
'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
|
||||
tableName, modelCol.name, databaseCol.name))
|
||||
pre_command = ' meta.bind = migrate_engine'
|
||||
tn, modelCol.name, databaseCol.name))
|
||||
|
||||
return (
|
||||
'\n'.join(decls),
|
||||
'\n'.join([pre_command] + ['%s%s' % (indent, line) for line in upgradeCommands]),
|
||||
'\n'.join([pre_command] + ['%s%s' % (indent, line) for line in downgradeCommands]))
|
||||
'\n'.join('%s%s' % (indent, line) for line in upgradeCommands),
|
||||
'\n'.join('%s%s' % (indent, line) for line in downgradeCommands))
|
||||
|
||||
def _db_can_handle_this_change(self,td):
|
||||
"""Check if the database can handle going from B to A."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user