def upgrade():
    bind = op.get_bind()
    engine = bind.engine

    op.add_column(
        ML2_PORT_BINDING,
        sa.Column('status',
                  sa.String(length=16),
                  nullable=False,
                  server_default=constants.PORT_BINDING_STATUS_ACTIVE))

    if (engine.name == MYSQL_ENGINE and not ndb.ndb_status(engine)):
        op.execute("ALTER TABLE ml2_port_bindings DROP PRIMARY KEY,"
                   "ADD PRIMARY KEY(port_id, host);")
    else:
        inspector = insp.from_engine(bind)
        fk_name = utils.get_foreign_key_constraint_name(
            engine, 'ml2_port_bindings', 'port_id')
        op.drop_constraint(fk_name, ML2_PORT_BINDING, type_='foreignkey')
        pk_constraint = inspector.get_pk_constraint(ML2_PORT_BINDING)
        op.drop_constraint(pk_constraint.get('name'),
                           ML2_PORT_BINDING,
                           type_='primary')
        op.create_primary_key(op.f('pk_ml2_port_bindings'), ML2_PORT_BINDING,
                              ['port_id', 'host'])
        op.create_foreign_key(fk_name,
                              ML2_PORT_BINDING,
                              'ports', ["port_id"], ["id"],
                              ondelete='CASCADE')
Esempio n. 2
0
def _init_events(engine, mysql_sql_mode=None, **kw):
    """Set up event listeners for MySQL."""

    if mysql_sql_mode is not None:
        @sqlalchemy.event.listens_for(engine, "connect")
        def _set_session_sql_mode(dbapi_con, connection_rec):
            cursor = dbapi_con.cursor()
            cursor.execute("SET SESSION sql_mode = %s", [mysql_sql_mode])

    @sqlalchemy.event.listens_for(engine, "first_connect")
    def _check_effective_sql_mode(dbapi_con, connection_rec):
        if mysql_sql_mode is not None:
            _set_session_sql_mode(dbapi_con, connection_rec)

        cursor = dbapi_con.cursor()
        cursor.execute("SHOW VARIABLES LIKE 'sql_mode'")
        realmode = cursor.fetchone()

        if realmode is None:
            LOG.warning('Unable to detect effective SQL mode')
        else:
            realmode = realmode[1]
            LOG.debug('MySQL server mode set to %s', realmode)
            if 'TRADITIONAL' not in realmode.upper() and \
                    'STRICT_ALL_TABLES' not in realmode.upper():
                LOG.warning(
                    "MySQL SQL mode is '%s', "
                    "consider enabling TRADITIONAL or STRICT_ALL_TABLES",
                    realmode)

    if ndb.ndb_status(engine):
        ndb.init_ndb_events(engine)
Esempio n. 3
0
def _init_events(engine, mysql_sql_mode=None, **kw):
    """Set up event listeners for MySQL."""

    if mysql_sql_mode is not None:
        @sqlalchemy.event.listens_for(engine, "connect")
        def _set_session_sql_mode(dbapi_con, connection_rec):
            cursor = dbapi_con.cursor()
            cursor.execute("SET SESSION sql_mode = %s", [mysql_sql_mode])

    @sqlalchemy.event.listens_for(engine, "first_connect")
    def _check_effective_sql_mode(dbapi_con, connection_rec):
        if mysql_sql_mode is not None:
            _set_session_sql_mode(dbapi_con, connection_rec)

        cursor = dbapi_con.cursor()
        cursor.execute("SHOW VARIABLES LIKE 'sql_mode'")
        realmode = cursor.fetchone()

        if realmode is None:
            LOG.warning('Unable to detect effective SQL mode')
        else:
            realmode = realmode[1]
            LOG.debug('MySQL server mode set to %s', realmode)
            if 'TRADITIONAL' not in realmode.upper() and \
                    'STRICT_ALL_TABLES' not in realmode.upper():
                LOG.warning(
                    "MySQL SQL mode is '%s', "
                    "consider enabling TRADITIONAL or STRICT_ALL_TABLES",
                    realmode)

    if ndb.ndb_status(engine):
        ndb.init_ndb_events(engine)
Esempio n. 4
0
 def test_ndb_enabled(self):
     self.init_db(True)
     self.assertTrue(ndb.ndb_status(self.engine))
     self.assertIsInstance(self.test_table.c.test1.type, TINYTEXT)
     self.assertIsInstance(self.test_table.c.test2.type, Text)
     self.assertIsInstance(self.test_table.c.test3.type, String)
     self.assertEqual(64, self.test_table.c.test3.type.length)
     self.assertEqual([], utils.get_non_ndbcluster_tables(self.engine))
Esempio n. 5
0
 def test_ndb_enabled(self):
     self.init_db(True)
     self.assertTrue(ndb.ndb_status(self.engine))
     self.assertIsInstance(self.test_table.c.test1.type, TINYTEXT)
     self.assertIsInstance(self.test_table.c.test2.type, Text)
     self.assertIsInstance(self.test_table.c.test3.type, String)
     self.assertEqual(64, self.test_table.c.test3.type.length)
     self.assertEqual([], utils.get_non_ndbcluster_tables(self.engine))
Esempio n. 6
0
 def test_ndb_disabled(self):
     self.init_db(False)
     self.assertFalse(ndb.ndb_status(self.engine))
     self.assertIsInstance(self.test_table.c.test1.type, String)
     self.assertEqual(255, self.test_table.c.test1.type.length)
     self.assertIsInstance(self.test_table.c.test2.type, String)
     self.assertEqual(4096, self.test_table.c.test2.type.length)
     self.assertIsInstance(self.test_table.c.test3.type, String)
     self.assertEqual(255, self.test_table.c.test3.type.length)
     self.assertEqual([], utils.get_non_innodb_tables(self.engine))
Esempio n. 7
0
 def test_ndb_disabled(self):
     self.init_db(False)
     self.assertFalse(ndb.ndb_status(self.engine))
     self.assertIsInstance(self.test_table.c.test1.type, String)
     self.assertEqual(255, self.test_table.c.test1.type.length)
     self.assertIsInstance(self.test_table.c.test2.type, String)
     self.assertEqual(4096, self.test_table.c.test2.type.length)
     self.assertIsInstance(self.test_table.c.test3.type, String)
     self.assertEqual(255, self.test_table.c.test3.type.length)
     self.assertEqual([], utils.get_non_innodb_tables(self.engine))
Esempio n. 8
0
File: api.py Progetto: brk3/neutron
def autonested_transaction(sess):
    """This is a convenience method to not bother with 'nested' parameter."""
    # If we are using MySQL Cluster (NDB), disable nesting.
    if ndb.ndb_status(sess.get_bind()):
        try:
            session_context = sess.begin(subtransactions=True, nested=False)
        except exc.InvalidRequestError:
            session_context = sess.begin(subtransactions=False, nested=False)
        finally:
            with session_context as tx:
                yield tx
    else:
        if sess.is_active:
            session_context = sess.begin(nested=True)
        else:
            session_context = sess.begin(subtransactions=True)
        with session_context as tx:
            yield tx
Esempio n. 9
0
def suspend_fk_constraints_for_col_alter(engine,
                                         table_name,
                                         column_name,
                                         referents=[]):
    """Detect foreign key constraints, drop, and recreate.

    This is used to guard against a column ALTER that on some backends
    cannot proceed unless foreign key constraints are not present.

    e.g.::

        from oslo_db.sqlalchemy.util import (
            suspend_fk_constraints_for_col_alter
        )

        with suspend_fk_constraints_for_col_alter(
            migrate_engine, "user_table",
            referents=[
                "local_user", "nonlocal_user", "project"
            ]):
            user_table.c.domain_id.alter(nullable=False)

    :param engine: a SQLAlchemy engine (or connection)

    :param table_name: target table name.  All foreign key constraints
     that refer to the table_name / column_name will be dropped and recreated.

    :param column_name: target column name.  all foreign key constraints
     which refer to this column, either partially or fully, will be dropped
     and recreated.

    :param referents: sequence of string table names to search for foreign
     key constraints.   A future version of this function may no longer
     require this argument, however for the moment it is required.

    """
    if (not ndb.ndb_status(engine)):
        yield
    else:
        with engine.connect() as conn:
            insp = inspect(conn)
            fks = []
            for ref_table_name in referents:
                for fk in insp.get_foreign_keys(ref_table_name):
                    if not fk.get('name'):
                        raise AssertionError("foreign key hasn't a name.")
                    if fk['referred_table'] == table_name and \
                            column_name in fk['referred_columns']:
                        fk['source_table'] = ref_table_name
                        if 'options' not in fk:
                            fk['options'] = {}
                        fks.append(fk)

            ctx = MigrationContext.configure(conn)
            op = Operations(ctx)

            for fk in fks:
                op.drop_constraint(fk['name'],
                                   fk['source_table'],
                                   type_="foreignkey")
            yield
            for fk in fks:
                op.create_foreign_key(
                    fk['name'],
                    fk['source_table'],
                    fk['referred_table'],
                    fk['constrained_columns'],
                    fk['referred_columns'],
                    onupdate=fk['options'].get('onupdate'),
                    ondelete=fk['options'].get('ondelete'),
                    deferrable=fk['options'].get('deferrable'),
                    initially=fk['options'].get('initially'),
                )
Esempio n. 10
0
def suspend_fk_constraints_for_col_alter(
        engine, table_name, column_name, referents=[]):
    """Detect foreign key constraints, drop, and recreate.

    This is used to guard against a column ALTER that on some backends
    cannot proceed unless foreign key constraints are not present.

    e.g.::

        from oslo_db.sqlalchemy.util import (
            suspend_fk_constraints_for_col_alter
        )

        with suspend_fk_constraints_for_col_alter(
            migrate_engine, "user_table",
            referents=[
                "local_user", "nonlocal_user", "project"
            ]):
            user_table.c.domain_id.alter(nullable=False)

    :param engine: a SQLAlchemy engine (or connection)

    :param table_name: target table name.  All foreign key constraints
     that refer to the table_name / column_name will be dropped and recreated.

    :param column_name: target column name.  all foreign key constraints
     which refer to this column, either partially or fully, will be dropped
     and recreated.

    :param referents: sequence of string table names to search for foreign
     key constraints.   A future version of this function may no longer
     require this argument, however for the moment it is required.

    """
    if (
        not ndb.ndb_status(engine)
    ):
        yield
    else:
        with engine.connect() as conn:
            insp = inspect(conn)
            fks = []
            for ref_table_name in referents:
                for fk in insp.get_foreign_keys(ref_table_name):
                    if not fk.get('name'):
                        raise AssertionError("foreign key hasn't a name.")
                    if fk['referred_table'] == table_name and \
                            column_name in fk['referred_columns']:
                        fk['source_table'] = ref_table_name
                        if 'options' not in fk:
                            fk['options'] = {}
                        fks.append(fk)

            ctx = MigrationContext.configure(conn)
            op = Operations(ctx)

            for fk in fks:
                op.drop_constraint(
                    fk['name'], fk['source_table'], type_="foreignkey")
            yield
            for fk in fks:
                op.create_foreign_key(
                    fk['name'], fk['source_table'],
                    fk['referred_table'],
                    fk['constrained_columns'],
                    fk['referred_columns'],
                    onupdate=fk['options'].get('onupdate'),
                    ondelete=fk['options'].get('ondelete'),
                    deferrable=fk['options'].get('deferrable'),
                    initially=fk['options'].get('initially'),
                )