Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
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]
Ejemplo n.º 4
0
 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,
         )
Ejemplo n.º 5
0
 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]
Ejemplo n.º 7
0
                            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",
Ejemplo n.º 8
0
    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', ))