almost done issue 12: generate downgrade method for schema migration
This commit is contained in:
parent
16144bb606
commit
9a44d9bd57
@ -80,25 +80,27 @@ class ModelGenerator(object):
|
|||||||
out.append("")
|
out.append("")
|
||||||
return '\n'.join(out)
|
return '\n'.join(out)
|
||||||
|
|
||||||
def toUpgradePython(self, indent=' '):
|
def toUpgradeDowngradePython(self, indent=' '):
|
||||||
''' Assume model is most current and database is out-of-date. '''
|
''' Assume model is most current and database is out-of-date. '''
|
||||||
|
|
||||||
decls = ['meta = MetaData(migrate_engine)']
|
decls = ['meta = MetaData(migrate_engine)']
|
||||||
for table in self.diff.tablesMissingInModel + self.diff.tablesMissingInDatabase:
|
for table in self.diff.tablesMissingInModel + self.diff.tablesMissingInDatabase:
|
||||||
decls.extend(self.getTableDefn(table))
|
decls.extend(self.getTableDefn(table))
|
||||||
|
|
||||||
cmds = []
|
upgradeCommands, downgradeCommands = [], []
|
||||||
for table in self.diff.tablesMissingInModel:
|
for table in self.diff.tablesMissingInModel:
|
||||||
tableName = table.name
|
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:
|
for table in self.diff.tablesMissingInDatabase:
|
||||||
tableName = table.name
|
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])
|
return ('\n'.join(decls),
|
||||||
|
'\n'.join(['%s%s' % (indent, line) for line in upgradeCommands]),
|
||||||
def toDowngradePython(self, indent=' '):
|
'\n'.join(['%s%s' % (indent, line) for line in downgradeCommands])
|
||||||
return ' pass #TODO DOWNGRADE'
|
)
|
||||||
|
|
||||||
def applyModel(self):
|
def applyModel(self):
|
||||||
''' Apply model to current database. '''
|
''' Apply model to current database. '''
|
||||||
|
@ -22,7 +22,6 @@ class PythonScript(base.BaseScript):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def make_update_script_for_model(cls,engine,oldmodel,model,repository,**opts):
|
def make_update_script_for_model(cls,engine,oldmodel,model,repository,**opts):
|
||||||
"""Create a migration script"""
|
"""Create a migration script"""
|
||||||
#cls.require_notfound(path) # TODO: yank?
|
|
||||||
|
|
||||||
# Compute differences.
|
# Compute differences.
|
||||||
if isinstance(repository, basestring):
|
if isinstance(repository, basestring):
|
||||||
@ -31,20 +30,17 @@ class PythonScript(base.BaseScript):
|
|||||||
oldmodel = loadModel(oldmodel)
|
oldmodel = loadModel(oldmodel)
|
||||||
model = loadModel(model)
|
model = loadModel(model)
|
||||||
diff = schemadiff.getDiffOfModelAgainstModel(oldmodel, model, engine, excludeTables=[repository.version_table])
|
diff = schemadiff.getDiffOfModelAgainstModel(oldmodel, model, engine, excludeTables=[repository.version_table])
|
||||||
upgradeDecls, upgradeCommands = genmodel.ModelGenerator(diff).toUpgradePython()
|
decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff).toUpgradeDowngradePython()
|
||||||
#downgradeCommands = genmodel.ModelGenerator(diff).toDowngradePython()
|
|
||||||
|
|
||||||
# TODO: Use the default script template (defined in the template
|
# Store differences into file.
|
||||||
# module) for now, but we might want to allow people to specify a
|
|
||||||
# different one later.
|
|
||||||
template_file = None
|
template_file = None
|
||||||
src = template.get_script(template_file)
|
src = template.get_script(template_file)
|
||||||
contents = open(src).read()
|
contents = open(src).read()
|
||||||
search = 'def upgrade():'
|
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 upgradeCommands: contents = contents.replace(' pass', upgradeCommands, 1)
|
||||||
#if downgradeCommands: contents = contents.replace(' pass', downgradeCommands, 1) # TODO
|
if downgradeCommands: contents = contents.replace(' pass', downgradeCommands, 1)
|
||||||
return contents # TODO: reinstate? open(path, 'w').write(contents)
|
return contents
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def verify_module(cls,path):
|
def verify_module(cls,path):
|
||||||
|
@ -50,10 +50,10 @@ class TestSchemaDiff(fixture.DB):
|
|||||||
# Model is defined but database is empty.
|
# Model is defined but database is empty.
|
||||||
assertDiff(True, [self.table_name], [], [])
|
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'])
|
diff = schemadiff.getDiffOfModelAgainstDatabase(self.meta, self.engine, excludeTables=['migrate_version'])
|
||||||
decl, commands = genmodel.ModelGenerator(diff).toUpgradePython()
|
decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff).toUpgradeDowngradePython()
|
||||||
self.assertEqualsIgnoreWhitespace(decl, '''
|
self.assertEqualsIgnoreWhitespace(decls, '''
|
||||||
meta = MetaData(migrate_engine)
|
meta = MetaData(migrate_engine)
|
||||||
tmp_schemadiff = Table('tmp_schemadiff',meta,
|
tmp_schemadiff = Table('tmp_schemadiff',meta,
|
||||||
Column('id',Integer(),primary_key=True,nullable=False),
|
Column('id',Integer(),primary_key=True,nullable=False),
|
||||||
@ -61,7 +61,8 @@ class TestSchemaDiff(fixture.DB):
|
|||||||
Column('data',UnicodeText(length=None)),
|
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.
|
# Create table in database, now model should match database.
|
||||||
self._applyLatestModel()
|
self._applyLatestModel()
|
||||||
|
@ -542,7 +542,7 @@ class TestShellDatabase(Shell,fixture.DB):
|
|||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# Operations to reverse the above upgrade go here.
|
# Operations to reverse the above upgrade go here.
|
||||||
pass
|
tmp_account_rundiffs.drop()
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Commit the change.
|
# Commit the change.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user