almost done issue 12: generate downgrade method for schema migration

This commit is contained in:
christian.simms 2008-04-24 18:52:36 +00:00
parent 16144bb606
commit 9a44d9bd57
4 changed files with 21 additions and 22 deletions

View File

@ -80,25 +80,27 @@ class ModelGenerator(object):
out.append("")
return '\n'.join(out)
def toUpgradePython(self, indent=' '):
def toUpgradeDowngradePython(self, indent=' '):
''' Assume model is most current and database is out-of-date. '''
decls = ['meta = MetaData(migrate_engine)']
for table in self.diff.tablesMissingInModel + self.diff.tablesMissingInDatabase:
decls.extend(self.getTableDefn(table))
cmds = []
upgradeCommands, downgradeCommands = [], []
for table in self.diff.tablesMissingInModel:
tableName = table.name
cmds.append("%(table)s.drop()" % {'table': tableName})
upgradeCommands.append("%(table)s.drop()" % {'table': tableName})
downgradeCommands.append("%(table)s.create()" % {'table': tableName})
for table in self.diff.tablesMissingInDatabase:
tableName = table.name
cmds.append("%(table)s.create()" % {'table': tableName})
upgradeCommands.append("%(table)s.create()" % {'table': tableName})
downgradeCommands.append("%(table)s.drop()" % {'table': tableName})
return '\n'.join(decls), '\n'.join(['%s%s' % (indent, line) for line in cmds])
def toDowngradePython(self, indent=' '):
return ' pass #TODO DOWNGRADE'
return ('\n'.join(decls),
'\n'.join(['%s%s' % (indent, line) for line in upgradeCommands]),
'\n'.join(['%s%s' % (indent, line) for line in downgradeCommands])
)
def applyModel(self):
''' Apply model to current database. '''

View File

@ -22,7 +22,6 @@ class PythonScript(base.BaseScript):
@classmethod
def make_update_script_for_model(cls,engine,oldmodel,model,repository,**opts):
"""Create a migration script"""
#cls.require_notfound(path) # TODO: yank?
# Compute differences.
if isinstance(repository, basestring):
@ -31,20 +30,17 @@ class PythonScript(base.BaseScript):
oldmodel = loadModel(oldmodel)
model = loadModel(model)
diff = schemadiff.getDiffOfModelAgainstModel(oldmodel, model, engine, excludeTables=[repository.version_table])
upgradeDecls, upgradeCommands = genmodel.ModelGenerator(diff).toUpgradePython()
#downgradeCommands = genmodel.ModelGenerator(diff).toDowngradePython()
decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff).toUpgradeDowngradePython()
# TODO: Use the default script template (defined in the template
# module) for now, but we might want to allow people to specify a
# different one later.
# Store differences into file.
template_file = None
src = template.get_script(template_file)
contents = open(src).read()
search = 'def upgrade():'
contents = contents.replace(search, upgradeDecls + '\n\n' + search, 1)
contents = contents.replace(search, decls + '\n\n' + search, 1)
if upgradeCommands: contents = contents.replace(' pass', upgradeCommands, 1)
#if downgradeCommands: contents = contents.replace(' pass', downgradeCommands, 1) # TODO
return contents # TODO: reinstate? open(path, 'w').write(contents)
if downgradeCommands: contents = contents.replace(' pass', downgradeCommands, 1)
return contents
@classmethod
def verify_module(cls,path):

View File

@ -50,10 +50,10 @@ class TestSchemaDiff(fixture.DB):
# Model is defined but database is empty.
assertDiff(True, [self.table_name], [], [])
# Check Python upgrade of database from updated model.
# Check Python upgrade and downgrade of database from updated model.
diff = schemadiff.getDiffOfModelAgainstDatabase(self.meta, self.engine, excludeTables=['migrate_version'])
decl, commands = genmodel.ModelGenerator(diff).toUpgradePython()
self.assertEqualsIgnoreWhitespace(decl, '''
decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff).toUpgradeDowngradePython()
self.assertEqualsIgnoreWhitespace(decls, '''
meta = MetaData(migrate_engine)
tmp_schemadiff = Table('tmp_schemadiff',meta,
Column('id',Integer(),primary_key=True,nullable=False),
@ -61,7 +61,8 @@ class TestSchemaDiff(fixture.DB):
Column('data',UnicodeText(length=None)),
)
''')
self.assertEqualsIgnoreWhitespace(commands, '''tmp_schemadiff.create()''')
self.assertEqualsIgnoreWhitespace(upgradeCommands, '''tmp_schemadiff.create()''')
self.assertEqualsIgnoreWhitespace(downgradeCommands, '''tmp_schemadiff.drop()''')
# Create table in database, now model should match database.
self._applyLatestModel()

View File

@ -542,7 +542,7 @@ class TestShellDatabase(Shell,fixture.DB):
def downgrade():
# Operations to reverse the above upgrade go here.
pass
tmp_account_rundiffs.drop()
""")
# Commit the change.