Add second migrate_repo for cells v2 database migrations

This sets up the framework for adding database migrations to run on the
new api database.  It splits migration commands so that they can run on
the current 'main' database or the new 'api' database.

bp: cells-v2-mapping
Change-Id: I73dee6fd51b74bd670a6dffa07e875bf86891e97
This commit is contained in:
Andrew Laski 2015-02-19 15:34:27 -05:00
parent 3c9b26c8af
commit 4934eca225
7 changed files with 50 additions and 21 deletions

View File

@ -21,19 +21,19 @@ from nova.db.sqlalchemy import migration
IMPL = migration
def db_sync(version=None):
def db_sync(version=None, database='main'):
"""Migrate the database to `version` or the most recent version."""
return IMPL.db_sync(version=version)
return IMPL.db_sync(version=version, database=database)
def db_version():
def db_version(database='main'):
"""Display the current database version."""
return IMPL.db_version()
return IMPL.db_version(database=database)
def db_initial_version():
def db_initial_version(database='main'):
"""The starting version for the database."""
return IMPL.db_initial_version()
return IMPL.db_initial_version(database=database)
def db_null_instance_uuid_scan(delete=False):

View File

@ -0,0 +1,4 @@
This is a database migration repository.
More information at
http://code.google.com/p/sqlalchemy-migrate/

View File

@ -0,0 +1,20 @@
[db_settings]
# Used to identify which repository this database is versioned under.
# You can use the name of your project.
repository_id=nova_api
# The name of the database table used to track the schema version.
# This name shouldn't already be used by your project.
# If this is changed once a database is under version control, you'll need to
# change the table name in each database too.
version_table=migrate_version
# When committing a change script, Migrate will attempt to generate the
# sql for all supported databases; normally, if one of them fails - probably
# because you don't have that database installed - it is ignored and the
# commit continues, perhaps ending successfully.
# Databases in this list MUST compile successfully during a commit, or the
# entire commit will fail. List the databases your application will actually
# be using to ensure your updates to that database work properly.
# This must be a list; example: ['postgres','sqlite']
required_dbs=[]

View File

@ -28,23 +28,25 @@ from nova.db.sqlalchemy import api as db_session
from nova import exception
from nova.i18n import _
INIT_VERSION = 215
_REPOSITORY = None
INIT_VERSION = {}
INIT_VERSION['main'] = 215
INIT_VERSION['api'] = 0
_REPOSITORY = {}
LOG = logging.getLogger(__name__)
get_engine = db_session.get_engine
def db_sync(version=None):
def db_sync(version=None, database='main'):
if version is not None:
try:
version = int(version)
except ValueError:
raise exception.NovaException(_("version should be an integer"))
current_version = db_version()
repository = _find_migrate_repo()
current_version = db_version(database)
repository = _find_migrate_repo(database)
if version is None or version > current_version:
return versioning_api.upgrade(get_engine(), repository, version)
else:
@ -52,8 +54,8 @@ def db_sync(version=None):
version)
def db_version():
repository = _find_migrate_repo()
def db_version(database='main'):
repository = _find_migrate_repo(database)
try:
return versioning_api.db_version(get_engine(), repository)
except versioning_exceptions.DatabaseNotControlledError as exc:
@ -62,7 +64,7 @@ def db_version():
meta.reflect(bind=engine)
tables = meta.tables
if len(tables) == 0:
db_version_control(INIT_VERSION)
db_version_control(INIT_VERSION[database])
return versioning_api.db_version(get_engine(), repository)
else:
LOG.exception(exc)
@ -72,8 +74,8 @@ def db_version():
_("Upgrade DB using Essex release first."))
def db_initial_version():
return INIT_VERSION
def db_initial_version(database='main'):
return INIT_VERSION[database]
def _process_null_records(table, col_name, check_fkeys, delete=False):
@ -151,12 +153,15 @@ def db_version_control(version=None):
return version
def _find_migrate_repo():
def _find_migrate_repo(database='main'):
"""Get the path for the migrate repository."""
global _REPOSITORY
rel_path = 'migrate_repo'
if database == 'api':
rel_path = os.path.join('api_migrations', 'migrate_repo')
path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'migrate_repo')
rel_path)
assert os.path.exists(path)
if _REPOSITORY is None:
_REPOSITORY = Repository(path)
return _REPOSITORY
if _REPOSITORY.get(database) is None:
_REPOSITORY[database] = Repository(path)
return _REPOSITORY[database]