Coverage for nova/db/migration.py: 98%
43 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-17 15:08 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-17 15:08 +0000
1# Copyright 2010 United States Government as represented by the
2# Administrator of the National Aeronautics and Space Administration.
3# All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
17import os
19from alembic import command as alembic_api
20from alembic import config as alembic_config
21from alembic.runtime import migration as alembic_migration
22from oslo_log import log as logging
24from nova.db.api import api as api_db_api
25from nova.db.main import api as main_db_api
26from nova import exception
28LOG = logging.getLogger(__name__)
31def _get_engine(database='main', context=None):
32 if database == 'main':
33 return main_db_api.get_engine(context=context)
35 if database == 'api': 35 ↛ exitline 35 didn't return from function '_get_engine' because the condition on line 35 was always true
36 return api_db_api.get_engine()
39def _find_alembic_conf(database='main'):
40 """Get the path for the alembic repository."""
42 path = os.path.join(
43 os.path.abspath(os.path.dirname(__file__)),
44 database, 'alembic.ini')
46 config = alembic_config.Config(path)
47 # we don't want to use the logger configuration from the file, which is
48 # only really intended for the CLI
49 # https://stackoverflow.com/a/42691781/613428
50 config.attributes['configure_logger'] = False
51 return config
54def _upgrade_alembic(engine, config, version):
55 # reuse the connection rather than creating a new one
56 with engine.begin() as connection:
57 config.attributes['connection'] = connection
58 alembic_api.upgrade(config, version or 'head')
61def db_sync(version=None, database='main', context=None):
62 """Migrate the database to `version` or the most recent version."""
64 if database not in ('main', 'api'):
65 raise exception.Invalid('%s is not a valid database' % database)
67 # if the user requested a specific version, check if it's an integer:
68 # if so, we're almost certainly in sqlalchemy-migrate land and won't
69 # support that
70 if version is not None and version.isdigit():
71 raise exception.Invalid(
72 'You requested an sqlalchemy-migrate database version; this is '
73 'no longer supported'
74 )
76 engine = _get_engine(database, context=context)
78 config = _find_alembic_conf(database)
79 # discard the URL stored in alembic.ini in favour of the URL configured
80 # for the engine, casting from 'sqlalchemy.engine.url.URL' to str in the
81 # process
82 # NOTE(sean-k-mooney): the engine has already url encoded the connection
83 # string using a mix of url encode styles for different parts of the url.
84 # since we are updating the alembic config parser instance we need to
85 # escape '%' to '%%' to account for ConfigParser's string interpolation.
86 url = engine.url.render_as_string(hide_password=False).replace('%', '%%')
87 config.set_main_option('sqlalchemy.url', url)
89 # apply anything later
90 LOG.info('Applying migration(s)')
92 _upgrade_alembic(engine, config, version)
94 LOG.info('Migration(s) applied')
97def db_version(database='main', context=None):
98 """Display the current database version."""
99 if database not in ('main', 'api'):
100 raise exception.Invalid('%s is not a valid database' % database)
102 engine = _get_engine(database, context=context)
104 with engine.connect() as conn:
105 m_context = alembic_migration.MigrationContext.configure(conn)
106 version = m_context.get_current_revision()
108 return version