Permalink
Browse files

Update db module from oslo-incubator

Update to sha 1ebf819e31dde74f4374c26a791458ccd25b29d9

Note:
 - database.backend is now defined in solum/openstack/common/db/api.py
 - Added the migration_cli for alembic

Change-Id: Ida884b1b72b4045e3c42c6b90ac0279ce0e19725
  • Loading branch information...
1 parent 6c8b902 commit 04bcb46d8e199135b2844cea0a0cc26663494b5b @asalkeld asalkeld committed Jan 28, 2014
@@ -21,10 +21,10 @@
# Options defined in solum.openstack.common.db.sqlalchemy.session
#
-# the filename to use with sqlite (string value)
+# The file name to use with SQLite (string value)
#sqlite_db=solum.sqlite
-# If true, use synchronous mode for sqlite (boolean value)
+# If True, SQLite uses synchronous mode (boolean value)
#sqlite_synchronous=true
@@ -142,15 +142,21 @@
# Options defined in solum.objects
#
-# The backend to use for persistence (string value)
-#backend=sqlalchemy
-
# The version of the schema that should be running: 'old',
# 'transition', 'new' (string value)
#schema_mode=new
#
+# Options defined in solum.openstack.common.db.api
+#
+
+# The backend to use for db (string value)
+# Deprecated group/name - [DEFAULT]/db_backend
+#backend=sqlalchemy
+
+
+#
# Options defined in solum.openstack.common.db.sqlalchemy.session
#
@@ -165,10 +171,11 @@
# slave database (string value)
#slave_connection=
-# timeout before idle sql connections are reaped (integer
+# Timeout before idle sql connections are reaped (integer
# value)
# Deprecated group/name - [DEFAULT]/sql_idle_timeout
# Deprecated group/name - [DATABASE]/sql_idle_timeout
+# Deprecated group/name - [sql]/idle_timeout
#idle_timeout=3600
# Minimum number of SQL connections to keep open in a pool
@@ -183,13 +190,13 @@
# Deprecated group/name - [DATABASE]/sql_max_pool_size
#max_pool_size=<None>
-# maximum db connection retries during startup. (setting -1
+# Maximum db connection retries during startup. (setting -1
# implies an infinite retry count) (integer value)
# Deprecated group/name - [DEFAULT]/sql_max_retries
# Deprecated group/name - [DATABASE]/sql_max_retries
#max_retries=10
-# interval between retries of opening a sql connection
+# Interval between retries of opening a sql connection
# (integer value)
# Deprecated group/name - [DEFAULT]/sql_retry_interval
# Deprecated group/name - [DATABASE]/reconnect_interval
View
@@ -2,6 +2,7 @@
module=db
module=db.sqlalchemy
+module=db.sqlalchemy.migration_cli
module=config
module=context
module=fixture
@@ -28,12 +28,11 @@
from oslo.config import cfg
from solum.objects import registry
+from solum.openstack.common.db import api # noqa
from solum.openstack.common import importutils
+
db_opts = [
- cfg.StrOpt('backend',
- default='sqlalchemy',
- help='The backend to use for persistence'),
cfg.StrOpt('schema_mode',
default='new',
help="The version of the schema that should be "
@@ -1,16 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Cloudscaling Group, Inc
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
@@ -0,0 +1,57 @@
+# Copyright (c) 2013 Rackspace Hosting
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Multiple DB API backend support.
+
+Supported configuration options:
+
+The following two parameters are in the 'database' group:
+`backend`: DB backend name or full module path to DB backend module.
+
+A DB backend module should implement a method named 'get_backend' which
+takes no arguments. The method can return any object that implements DB
+API methods.
+"""
+
+from oslo.config import cfg
+
+from solum.openstack.common import importutils
+
+
+db_opts = [
+ cfg.StrOpt('backend',
+ default='sqlalchemy',
+ deprecated_name='db_backend',
+ deprecated_group='DEFAULT',
+ help='The backend to use for db'),
+]
+
+CONF = cfg.CONF
+CONF.register_opts(db_opts, 'database')
+
+
+class DBAPI(object):
+ def __init__(self, backend_mapping=None):
+ if backend_mapping is None:
+ backend_mapping = {}
+ backend_name = CONF.database.backend
+ # Import the untranslated name if we don't have a
+ # mapping.
+ backend_path = backend_mapping.get(backend_name, backend_name)
+ backend_mod = importutils.import_module(backend_path)
+ self.__backend = backend_mod.get_backend()
+
+ def __getattr__(self, key):
+ return getattr(self.__backend, key)
@@ -1,5 +1,3 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
@@ -18,7 +16,7 @@
"""DB related custom exceptions."""
-from solum.openstack.common.gettextutils import _ # noqa
+from solum.openstack.common.gettextutils import _
class DBError(Exception):
@@ -49,3 +47,8 @@ class DbMigrationError(DBError):
"""Wraps migration specific exception."""
def __init__(self, message=None):
super(DbMigrationError, self).__init__(str(message))
+
+
+class DBConnectionError(DBError):
+ """Wraps connection specific exception."""
+ pass
@@ -1,16 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Cloudscaling Group, Inc
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
@@ -36,53 +36,25 @@
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
-import distutils.version as dist_version
import os
import re
-import migrate
from migrate.changeset import ansisql
from migrate.changeset.databases import sqlite
-from migrate.versioning import util as migrate_util
+from migrate import exceptions as versioning_exceptions
+from migrate.versioning import api as versioning_api
+from migrate.versioning.repository import Repository
import sqlalchemy
from sqlalchemy.schema import UniqueConstraint
from solum.openstack.common.db import exception
from solum.openstack.common.db.sqlalchemy import session as db_session
-from solum.openstack.common.gettextutils import _ # noqa
-
-
-@migrate_util.decorator
-def patched_with_engine(f, *a, **kw):
- url = a[0]
- engine = migrate_util.construct_engine(url, **kw)
-
- try:
- kw['engine'] = engine
- return f(*a, **kw)
- finally:
- if isinstance(engine, migrate_util.Engine) and engine is not url:
- migrate_util.log.debug('Disposing SQLAlchemy engine %s', engine)
- engine.dispose()
-
-
-# TODO(jkoelker) When migrate 0.7.3 is released and nova depends
-# on that version or higher, this can be removed
-MIN_PKG_VERSION = dist_version.StrictVersion('0.7.3')
-if (not hasattr(migrate, '__version__') or
- dist_version.StrictVersion(migrate.__version__) < MIN_PKG_VERSION):
- migrate_util.with_engine = patched_with_engine
+from solum.openstack.common.gettextutils import _
-# NOTE(jkoelker) Delay importing migrate until we are patched
-from migrate import exceptions as versioning_exceptions
-from migrate.versioning import api as versioning_api
-from migrate.versioning.repository import Repository
-
-_REPOSITORY = None
-
get_engine = db_session.get_engine
@@ -220,13 +192,30 @@ def db_sync(abs_path, version=None, init_version=0):
current_version = db_version(abs_path, init_version)
repository = _find_migrate_repo(abs_path)
+ _db_schema_sanity_check()
if version is None or version > current_version:
return versioning_api.upgrade(get_engine(), repository, version)
else:
return versioning_api.downgrade(get_engine(), repository,
version)
+def _db_schema_sanity_check():
+ engine = get_engine()
+ if engine.name == 'mysql':
+ onlyutf8_sql = ('SELECT TABLE_NAME,TABLE_COLLATION '
+ 'from information_schema.TABLES '
+ 'where TABLE_SCHEMA=%s and '
+ 'TABLE_COLLATION NOT LIKE "%%utf8%%"')
+
+ table_names = [res[0] for res in engine.execute(onlyutf8_sql,
+ engine.url.database)]
+ if len(table_names) > 0:
+ raise ValueError(_('Tables "%s" have non utf8 collation, '
+ 'please make sure all tables are CHARSET=utf8'
+ ) % ','.join(table_names))
+
+
def db_version(abs_path, init_version):
"""Show the current version of the repository.
@@ -241,14 +230,15 @@ def db_version(abs_path, init_version):
engine = get_engine()
meta.reflect(bind=engine)
tables = meta.tables
- if len(tables) == 0:
+ if len(tables) == 0 or 'alembic_version' in tables:
db_version_control(abs_path, init_version)
return versioning_api.db_version(get_engine(), repository)
else:
- # Some pre-Essex DB's may not be version controlled.
- # Require them to upgrade using Essex first.
raise exception.DbMigrationError(
- message=_("Upgrade DB using Essex release first."))
+ message=_(
+ "The database is not under version control, but has "
+ "tables. Please stamp the current version of the schema "
+ "manually."))
def db_version_control(abs_path, version=None):
@@ -270,9 +260,6 @@ def _find_migrate_repo(abs_path):
:param abs_path: Absolute path to migrate repository
"""
- global _REPOSITORY
if not os.path.exists(abs_path):
raise exception.DbMigrationError("Path %s not found" % abs_path)
- if _REPOSITORY is None:
- _REPOSITORY = Repository(abs_path)
- return _REPOSITORY
+ return Repository(abs_path)
Oops, something went wrong.

0 comments on commit 04bcb46

Please sign in to comment.