def _ensure_backend_available(cls, url): url = sa_url.make_url(str(url)) try: eng = sqlalchemy.create_engine(url) except ImportError as i_e: # SQLAlchemy performs an "import" of the DBAPI module # within create_engine(). So if ibm_db_sa, cx_oracle etc. # isn't installed, we get an ImportError here. LOG.info("The %(dbapi)s backend is unavailable: %(err)s", dict(dbapi=url.drivername, err=i_e)) raise exception.BackendNotAvailable( "Backend '%s' is unavailable: No DBAPI installed" % url.drivername) else: try: conn = eng.connect() except sqlalchemy.exc.DBAPIError as d_e: # upon connect, SQLAlchemy calls dbapi.connect(). This # usually raises OperationalError and should always at # least raise a SQLAlchemy-wrapped DBAPI Error. LOG.info("The %(dbapi)s backend is unavailable: %(err)s", dict(dbapi=url.drivername, err=d_e)) raise exception.BackendNotAvailable( "Backend '%s' is unavailable: Could not connect" % url.drivername) else: conn.close() return eng
def backend_for_database_type(cls, database_type): """Return the ``Backend`` for the given database type. """ try: backend = cls.backends_by_database_type[database_type] except KeyError: raise exception.BackendNotAvailable(database_type) else: return backend._verify()
def backend_for_database_type(cls, database_type): """Return and verify the ``Backend`` for the given database type. Creates the engine if it does not already exist and raises ``BackendNotAvailable`` if it cannot be produced. :return: a base ``Engine`` that allows provisioning of databases. :raises: ``BackendNotAvailable``, if an engine for this backend cannot be produced. """ try: backend = cls.backends_by_database_type[database_type] except KeyError: raise exception.BackendNotAvailable(database_type) else: return backend._verify()
def _verify(self): """Verify that this ``Backend`` is available and provisionable. :return: this ``Backend`` :raises: ``BackendNotAvailable`` if the backend is not available. """ if not self.verified: try: eng = self._ensure_backend_available(self.url) except exception.BackendNotAvailable: raise else: self.engine = eng finally: self.verified = True if self.engine is None: raise exception.BackendNotAvailable(self.database_type) return self