def mock_helper(command, *args, **kwargs): if '_get_schema_columns' in command: # Creating exception exactly how SQLAlchemy does raise DBAPIError.instance( ''' SELECT /* sqlalchemy:_get_schema_columns */ ic.table_name, ic.column_name, ic.data_type, ic.character_maximum_length, ic.numeric_precision, ic.numeric_scale, ic.is_nullable, ic.column_default, ic.is_identity, ic.comment FROM information_schema.columns ic WHERE ic.table_schema='schema_name' ORDER BY ic.ordinal_position''', {'table_schema': 'TESTSCHEMA'}, ProgrammingError("Information schema query returned too much data. Please repeat query with more " "selective predicates.", 90030), Error, hide_parameters=False, connection_invalidated=False, dialect=SnowflakeDialect(), ismulti=None ) else: return original_execute(command, *args, **kwargs)
def test_db_check_dbapi_error(mocker, db): exception = DBAPIError.instance("", [], Exception(), Exception) engine_connect = mocker.patch.object(db.engine, "connect") engine_connect.side_effect = exception errors = checks.check_database_connected(db) assert len(errors) == 1 assert errors[0].id == health.ERROR_DB_API_EXCEPTION
def _read_only_connect(dialect, connection_info): """ Creator function invoked for creating read only connections Note that the parameters are first created using a partial. SqlAlchemy invokes this without parameters. Every time a new connection is created, we query plusmoin for the current list of servers, and serve these in a round robin fashion. @param dialect: The SqlAlchemy Dialect class that represents our database @param connection_info: dict defining host, port, user, password and database. @returns: A dbapi object """ global _last_host try: plusmoin = _plusmoin_status() if plusmoin: if len(plusmoin['clusters']) == 0: raise Exception('Plusmoin advertises no available servers') available = list(plusmoin['clusters'][0]['slaves']) if plusmoin['clusters'][0]['has_master']: available.append(plusmoin['clusters'][0]['master']) if len(available) == 0: raise Exception('Plusmoin advertises no available servers') try: p = available.index(_last_host) host = available[(p+1) % len(available)] except ValueError: host = available[0] _last_host = host else: host = connection_info logger = logging.getLogger('db_load_balancing') logger.debug("Read only connection using %s", str(host)) return dialect.connect( user=connection_info['user'], password=connection_info['password'], database=connection_info['database'], host=host['host'], port=host['port'] ) except Exception as e: import sys raise DBAPIError.instance( None, None, e, dialect.dbapi.Error, connection_invalidated= dialect.is_disconnect(e, None, None)), \ None, sys.exc_info()[2]
def _execute(self, query, *multiparams, **params): try: result = yield from super()._execute(query, *multiparams, **params) return result except self._dialect.dbapi.Error as e: if isinstance(query, str): statement = query params = params else: compiled = query.compile(dialect=self._dialect) statement = str(compiled) params = compiled.params raise DBAPIError.instance( statement, params, e, self._dialect.dbapi.Error, dialect=self._dialect, )
def _execute(self, query, *multiparams, **params): try: result = yield from super()._execute(query, *multiparams, **params) return result except self._dialect.dbapi.Error as e: if isinstance(query, str): statement = query params = params else: compiled = query.compile(dialect=self._dialect) statement = str(compiled) params = compiled.params raise DBAPIError.instance( statement, params, e, self._dialect.dbapi.Error, dialect=self._dialect, )
def _read_write_connect(dialect, connection_info): """ Creator function invoked for creating read/write connections Note that the parameters are first created using a partial. SqlAlchemy invokes this without parameters. Every time a new connection is created, we query plusmoin for the current master and return a connection to that host. @param dialect: The SqlAlchemy Dialect class that represents our database @param connection_info: dict defining host, port, user, password and database. @returns: A dbapi object """ try: plusmoin = _plusmoin_status() if plusmoin: if len(plusmoin['clusters']) == 0 or not plusmoin['clusters'][0]['has_master']: raise Exception('Plusmoin advertises no available masters') master = plusmoin['clusters'][0]['master'] else: master = connection_info logger = logging.getLogger('db_load_balancing') logger.debug("Read/write connection using %s", str(master)) return dialect.connect( user=connection_info['user'], password=connection_info['password'], database=connection_info['database'], host=master['host'], port=master['port'] ) except Exception as e: import sys raise DBAPIError.instance( None, None, e, dialect.dbapi.Error, connection_invalidated= dialect.is_disconnect(e, None, None)), \ None, sys.exc_info()[2]
level=100, id="tests.checks.E001", obj=obj) assert message == message2 message3 = checks.Error("some error", level=101, id="tests.checks.E001", obj=obj) assert message != message3 @pytest.mark.parametrize( "exception", [SQLAlchemyError(), DBAPIError.instance("", [], Exception(), Exception)], ) def test_check_migrations_applied_cannot_check_migrations( exception, mocker, db, migrate): engine_connect = mocker.patch.object(db.engine, "connect") engine_connect.side_effect = exception errors = checks.check_migrations_applied(migrate) assert len(errors) == 1 assert errors[0].id == health.INFO_CANT_CHECK_MIGRATIONS def test_check_migrations_applied_success(mocker, db, migrate): get_heads = mocker.patch("alembic.script.ScriptDirectory.get_heads", return_value=("17164a7d1c2e", )) get_current_heads = mocker.patch( "alembic.migration.MigrationContext.get_current_heads",
assert str(message) == "test: (tests.checks.E001) some error" assert ( repr(message) == "<Error: level=100, msg='some error', " "hint=None, obj='test', id='tests.checks.E001'>" ) message2 = checks.Error("some error", level=100, id="tests.checks.E001", obj=obj) assert message == message2 message3 = checks.Error("some error", level=101, id="tests.checks.E001", obj=obj) assert message != message3 @pytest.mark.parametrize( "exception", [SQLAlchemyError(), DBAPIError.instance("", [], Exception(), Exception)], ) def test_check_migrations_applied_cannot_check_migrations( exception, mocker, db, migrate ): engine_connect = mocker.patch.object(db.engine, "connect") engine_connect.side_effect = exception errors = checks.check_migrations_applied(migrate) assert len(errors) == 1 assert errors[0].id == health.INFO_CANT_CHECK_MIGRATIONS def test_check_migrations_applied_success(mocker, db, migrate): get_heads = mocker.patch( "alembic.script.ScriptDirectory.get_heads", return_value=("17164a7d1c2e",) )
level=100, id='tests.checks.E001', obj=obj) assert message == message2 message3 = checks.Error('some error', level=101, id='tests.checks.E001', obj=obj) assert message != message3 @pytest.mark.parametrize( 'exception', [SQLAlchemyError(), DBAPIError.instance('', [], Exception(), Exception)]) def test_check_migrations_applied_cannot_check_migrations( exception, mocker, db, migrate): engine_connect = mocker.patch.object(db.engine, 'connect') engine_connect.side_effect = exception errors = checks.check_migrations_applied(migrate) assert len(errors) == 1 assert errors[0].id == health.INFO_CANT_CHECK_MIGRATIONS def test_check_migrations_applied_success(mocker, db, migrate): get_heads = mocker.patch('alembic.script.ScriptDirectory.get_heads', return_value=('17164a7d1c2e', )) get_current_heads = mocker.patch( 'alembic.migration.MigrationContext.get_current_heads', return_value=('17164a7d1c2e', ))