This generates a prepopulated template with the changes needed to match the
database state with the models. You should inspect the autogenerated template
to ensure that the proper models have been altered.
+When running the above command you will probably get the following error
+message::
+
+ Multiple heads are present; please specify the head revision on which the
+ new revision should be based, or perform a merge.
+
+This is alembic telling you that it does not know which branch (contract or
+expand) to generate the revision for. You must decide, based on whether you
+are doing contracting or expanding changes to the schema, and provide either
+the ``--contract`` or ``--expand`` option. If you have both types of changes,
+you must run the command twice, once with each option, and then manually edit
+the generated revision scripts to separate the migration operations.
In rare circumstances, you may want to start with an empty migration template
and manually author the changes necessary for an upgrade. You can create a
-blank file via::
+blank file for a branch via::
+
+ neutron-db-manage revision -m "description of revision" --expand
+ neutron-db-manage revision -m "description of revision" --contract
- neutron-db-manage revision -m "description of revision"
+**NOTE:** If you use above command you should check that migration is created
+in a directory that is named as current release. If not, please raise the issue
+with the development team (IRC, mailing list, launchpad bug).
The timeline on each alembic branch should remain linear and not interleave
with other branches, so that there is a clear path when upgrading. To verify
return sub.add_parser(cmd, help=getattr(alembic_command, cmd).__doc__)
+def add_branch_options(parser):
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument('--expand', action='store_true')
+ group.add_argument('--contract', action='store_true')
+
+
def _find_milestone_revisions(config, milestone, branch=None):
"""Return the revision(s) for a given milestone."""
script = alembic_script.ScriptDirectory.from_config(config)
def do_revision(config, cmd):
'''Generate new revision files, one per branch.'''
- do_alembic_command(config, cmd,
- message=CONF.command.message,
- autogenerate=CONF.command.autogenerate,
- sql=CONF.command.sql)
+ kwargs = {
+ 'message': CONF.command.message,
+ 'autogenerate': CONF.command.autogenerate,
+ 'sql': CONF.command.sql,
+ }
+ if CONF.command.expand:
+ kwargs['head'] = 'expand@head'
+ elif CONF.command.contract:
+ kwargs['head'] = 'contract@head'
+
+ do_alembic_command(config, cmd, **kwargs)
update_head_file(config)
default='',
help='Change MySQL storage engine of current '
'existing tables')
-
- group = parser.add_mutually_exclusive_group()
- group.add_argument('--expand', action='store_true')
- group.add_argument('--contract', action='store_true')
+ add_branch_options(parser)
parser.set_defaults(func=do_upgrade)
parser.add_argument('-m', '--message')
parser.add_argument('--autogenerate', action='store_true')
parser.add_argument('--sql', action='store_true')
+ add_branch_options(parser)
parser.set_defaults(func=do_revision)
expected_kwargs
)
self.assertEqual(len(self.projects), update.call_count)
+ update.reset_mock()
+
+ for kwarg in expected_kwargs:
+ kwarg['sql'] = False
+ kwarg['head'] = 'expand@head'
+
+ self._main_test_helper(
+ ['prog', 'revision', '-m', 'message', '--expand'],
+ 'revision',
+ expected_kwargs
+ )
+ self.assertEqual(len(self.projects), update.call_count)
+ update.reset_mock()
+
+ for kwarg in expected_kwargs:
+ kwarg['head'] = 'contract@head'
+
+ self._main_test_helper(
+ ['prog', 'revision', '-m', 'message', '--contract'],
+ 'revision',
+ expected_kwargs
+ )
+ self.assertEqual(len(self.projects), update.call_count)
def test_database_sync_revision(self):
self._test_database_sync_revision()