summaryrefslogtreecommitdiff
path: root/oslo_db/sqlalchemy/provision.py
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-02-03 19:58:34 +0000
committerGerrit Code Review <review@openstack.org>2015-02-03 19:58:34 +0000
commitaa6fc4e2bd985c8a115de53f958ad16256a90243 (patch)
treee1c283f06762c997db64ede896c047d8520cd60d /oslo_db/sqlalchemy/provision.py
parent67810cc83b37c75d5532f5cd697b578df2db6740 (diff)
parentdcd137a6d5f29600c87060f9ca1e169f88211c15 (diff)
downloadoslo-db-aa6fc4e2bd985c8a115de53f958ad16256a90243.tar.gz
Merge "Implement backend-specific drop_all_objects for provisioning."
Diffstat (limited to 'oslo_db/sqlalchemy/provision.py')
-rw-r--r--oslo_db/sqlalchemy/provision.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/oslo_db/sqlalchemy/provision.py b/oslo_db/sqlalchemy/provision.py
index cce7025..ffb0cca 100644
--- a/oslo_db/sqlalchemy/provision.py
+++ b/oslo_db/sqlalchemy/provision.py
@@ -27,9 +27,11 @@ import six
from six import moves
import sqlalchemy
from sqlalchemy.engine import url as sa_url
+from sqlalchemy import schema
from oslo_db._i18n import _LI
from oslo_db import exception
+from oslo_db.sqlalchemy.compat import utils as compat_utils
from oslo_db.sqlalchemy import session
from oslo_db.sqlalchemy import utils
@@ -56,6 +58,9 @@ class ProvisionedDatabase(object):
self.backend.create_named_database(self.db_token)
self.engine = self.backend.provisioned_engine(self.db_token)
+ def drop_all_objects(self):
+ self.backend.drop_all_objects(self.engine)
+
def dispose(self):
self.engine.dispose()
self.backend.drop_named_database(self.db_token)
@@ -179,6 +184,15 @@ class Backend(object):
self.engine, ident,
conditional=conditional)
+ def drop_all_objects(self, engine):
+ """Drop all database objects.
+
+ Drops all database objects remaining on the default schema of the
+ given engine.
+
+ """
+ self.impl.drop_all_objects(engine)
+
def database_exists(self, ident):
"""Return True if a database of the given name exists."""
@@ -246,6 +260,8 @@ class BackendImpl(object):
default_engine_kwargs = {}
+ supports_drop_fk = True
+
@classmethod
def all_impls(cls):
"""Return an iterator of all possible BackendImpl objects.
@@ -294,6 +310,49 @@ class BackendImpl(object):
def drop_named_database(self, engine, ident, conditional=False):
"""Drop a database with the given name."""
+ def drop_all_objects(self, engine):
+ """Drop all database objects.
+
+ Drops all database objects remaining on the default schema of the
+ given engine.
+
+ Per-db implementations will also need to drop items specific to those
+ systems, such as sequences, custom types (e.g. pg ENUM), etc.
+
+ """
+
+ with engine.begin() as conn:
+ inspector = sqlalchemy.inspect(engine)
+ metadata = schema.MetaData()
+ tbs = []
+ all_fks = []
+
+ for table_name in inspector.get_table_names():
+ fks = []
+ for fk in inspector.get_foreign_keys(table_name):
+ # note that SQLite reflection does not have names
+ # for foreign keys until SQLAlchemy 1.0
+ if not fk['name']:
+ continue
+ fks.append(
+ schema.ForeignKeyConstraint((), (), name=fk['name'])
+ )
+ table = schema.Table(table_name, metadata, *fks)
+ tbs.append(table)
+ all_fks.extend(fks)
+
+ if self.supports_drop_fk:
+ for fkc in all_fks:
+ conn.execute(schema.DropConstraint(fkc))
+
+ for table in tbs:
+ conn.execute(schema.DropTable(table))
+
+ self.drop_additional_objects(conn)
+
+ def drop_additional_objects(self, conn):
+ pass
+
def provisioned_engine(self, base_url, ident):
"""Return a provisioned engine.
@@ -344,6 +403,9 @@ class MySQLBackendImpl(BackendImpl):
@BackendImpl.impl.dispatch_for("sqlite")
class SQLiteBackendImpl(BackendImpl):
+
+ supports_drop_fk = False
+
def create_opportunistic_driver_url(self):
return "sqlite://"
@@ -394,6 +456,12 @@ class PostgresqlBackendImpl(BackendImpl):
else:
conn.execute("DROP DATABASE %s" % ident)
+ def drop_additional_objects(self, conn):
+ enums = compat_utils.get_postgresql_enums(conn)
+
+ for e in enums:
+ conn.execute("DROP TYPE %s" % e)
+
def database_exists(self, engine, ident):
return bool(
engine.scalar(