~ubuntu-branches/ubuntu/vivid/ceilometer/vivid-proposed

« back to all changes in this revision

Viewing changes to ceilometer/openstack/common/db/sqlalchemy/migration.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2014-06-13 13:20:35 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20140613132035-42ibzh8j7ww2q31i
Tags: 2014.2~b1-0ubuntu1
* New upstream release.
* debian/control: Open up juno release
* debian/patches/fix-requirements.patch: Refreshed.
* debian/rules: Patch the ceilometer.conf.sample directly since
  the configuration files are generated by a tool.
* debian/ceilometer-common.install: Drop sources.json.

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
from sqlalchemy.schema import UniqueConstraint
52
52
 
53
53
from ceilometer.openstack.common.db import exception
54
 
from ceilometer.openstack.common.db.sqlalchemy import session as db_session
55
54
from ceilometer.openstack.common.gettextutils import _
56
55
 
57
56
 
58
 
get_engine = db_session.get_engine
59
 
 
60
 
 
61
57
def _get_unique_constraints(self, table):
62
58
    """Retrieve information about existing unique constraints of the table
63
59
 
172
168
                                sqlite.SQLiteConstraintGenerator)
173
169
 
174
170
 
175
 
def db_sync(abs_path, version=None, init_version=0):
 
171
def db_sync(engine, abs_path, version=None, init_version=0, sanity_check=True):
176
172
    """Upgrade or downgrade a database.
177
173
 
178
174
    Function runs the upgrade() or downgrade() functions in change scripts.
179
175
 
 
176
    :param engine:       SQLAlchemy engine instance for a given database
180
177
    :param abs_path:     Absolute path to migrate repository.
181
178
    :param version:      Database will upgrade/downgrade until this version.
182
179
                         If None - database will update to the latest
183
180
                         available version.
184
181
    :param init_version: Initial database version
 
182
    :param sanity_check: Require schema sanity checking for all tables
185
183
    """
 
184
 
186
185
    if version is not None:
187
186
        try:
188
187
            version = int(version)
190
189
            raise exception.DbMigrationError(
191
190
                message=_("version should be an integer"))
192
191
 
193
 
    current_version = db_version(abs_path, init_version)
 
192
    current_version = db_version(engine, abs_path, init_version)
194
193
    repository = _find_migrate_repo(abs_path)
195
 
    _db_schema_sanity_check()
 
194
    if sanity_check:
 
195
        _db_schema_sanity_check(engine)
196
196
    if version is None or version > current_version:
197
 
        return versioning_api.upgrade(get_engine(), repository, version)
 
197
        return versioning_api.upgrade(engine, repository, version)
198
198
    else:
199
 
        return versioning_api.downgrade(get_engine(), repository,
 
199
        return versioning_api.downgrade(engine, repository,
200
200
                                        version)
201
201
 
202
202
 
203
 
def _db_schema_sanity_check():
204
 
    engine = get_engine()
 
203
def _db_schema_sanity_check(engine):
 
204
    """Ensure all database tables were created with required parameters.
 
205
 
 
206
    :param engine:  SQLAlchemy engine instance for a given database
 
207
 
 
208
    """
 
209
 
205
210
    if engine.name == 'mysql':
206
211
        onlyutf8_sql = ('SELECT TABLE_NAME,TABLE_COLLATION '
207
212
                        'from information_schema.TABLES '
208
213
                        'where TABLE_SCHEMA=%s and '
209
214
                        'TABLE_COLLATION NOT LIKE "%%utf8%%"')
210
215
 
211
 
        table_names = [res[0] for res in engine.execute(onlyutf8_sql,
212
 
                                                        engine.url.database)]
 
216
        # NOTE(morganfainberg): exclude the sqlalchemy-migrate and alembic
 
217
        # versioning tables from the tables we need to verify utf8 status on.
 
218
        # Non-standard table names are not supported.
 
219
        EXCLUDED_TABLES = ['migrate_version', 'alembic_version']
 
220
 
 
221
        table_names = [res[0] for res in
 
222
                       engine.execute(onlyutf8_sql, engine.url.database) if
 
223
                       res[0].lower() not in EXCLUDED_TABLES]
 
224
 
213
225
        if len(table_names) > 0:
214
226
            raise ValueError(_('Tables "%s" have non utf8 collation, '
215
227
                               'please make sure all tables are CHARSET=utf8'
216
228
                               ) % ','.join(table_names))
217
229
 
218
230
 
219
 
def db_version(abs_path, init_version):
 
231
def db_version(engine, abs_path, init_version):
220
232
    """Show the current version of the repository.
221
233
 
 
234
    :param engine:  SQLAlchemy engine instance for a given database
222
235
    :param abs_path: Absolute path to migrate repository
223
236
    :param version:  Initial database version
224
237
    """
225
238
    repository = _find_migrate_repo(abs_path)
226
239
    try:
227
 
        return versioning_api.db_version(get_engine(), repository)
 
240
        return versioning_api.db_version(engine, repository)
228
241
    except versioning_exceptions.DatabaseNotControlledError:
229
242
        meta = sqlalchemy.MetaData()
230
 
        engine = get_engine()
231
243
        meta.reflect(bind=engine)
232
244
        tables = meta.tables
233
245
        if len(tables) == 0 or 'alembic_version' in tables:
234
 
            db_version_control(abs_path, init_version)
235
 
            return versioning_api.db_version(get_engine(), repository)
 
246
            db_version_control(engine, abs_path, version=init_version)
 
247
            return versioning_api.db_version(engine, repository)
236
248
        else:
237
249
            raise exception.DbMigrationError(
238
250
                message=_(
241
253
                    "manually."))
242
254
 
243
255
 
244
 
def db_version_control(abs_path, version=None):
 
256
def db_version_control(engine, abs_path, version=None):
245
257
    """Mark a database as under this repository's version control.
246
258
 
247
259
    Once a database is under version control, schema changes should
248
260
    only be done via change scripts in this repository.
249
261
 
 
262
    :param engine:  SQLAlchemy engine instance for a given database
250
263
    :param abs_path: Absolute path to migrate repository
251
264
    :param version:  Initial database version
252
265
    """
253
266
    repository = _find_migrate_repo(abs_path)
254
 
    versioning_api.version_control(get_engine(), repository, version)
 
267
    versioning_api.version_control(engine, repository, version)
255
268
    return version
256
269
 
257
270