# License for the specific language governing permissions and limitations
# under the License.
+import contextlib
import functools
from alembic import context
from alembic import op
import sqlalchemy as sa
+from sqlalchemy.engine import reflection
def skip_if_offline(func):
"WHERE NOT table_exist(%(name)r);" %
{'name': table_name,
'columns': values})
+
+
+def remove_foreign_keys(table, foreign_keys):
+ for fk in foreign_keys:
+ op.drop_constraint(
+ name=fk['name'],
+ table_name=table,
+ type_='foreignkey'
+ )
+
+
+def create_foreign_keys(table, foreign_keys):
+ for fk in foreign_keys:
+ op.create_foreign_key(
+ name=fk['name'],
+ source=table,
+ referent=fk['referred_table'],
+ local_cols=fk['constrained_columns'],
+ remote_cols=fk['referred_columns'],
+ ondelete='CASCADE'
+ )
+
+
+@contextlib.contextmanager
+def remove_fks_from_table(table):
+ try:
+ inspector = reflection.Inspector.from_engine(op.get_bind())
+ foreign_keys = inspector.get_foreign_keys(table)
+ remove_foreign_keys(table, foreign_keys)
+ yield
+ finally:
+ create_foreign_keys(table, foreign_keys)
from alembic import op
import sqlalchemy as sa
-from sqlalchemy.engine import reflection
+
+from neutron.db import migration
TABLE_NAME = 'routerl3agentbindings'
PK_NAME = 'pk_routerl3agentbindings'
-fk_names = {'postgresql':
- {'router_id':
- 'routerl3agentbindings_router_id_fkey',
- 'l3_agent_id':
- 'routerl3agentbindings_l3_agent_id_fkey'},
- 'mysql':
- {'router_id':
- 'routerl3agentbindings_ibfk_2',
- 'l3_agent_id':
- 'routerl3agentbindings_ibfk_1'}}
-
def upgrade():
# In order to sanitize the data during migration,
op.drop_column(TABLE_NAME, 'id')
- # DB2 doesn't support nullable column in primary key
- if context.bind.dialect.name == 'ibm_db_sa':
- op.alter_column(
- table_name=TABLE_NAME,
- column_name='router_id',
- nullable=False
- )
- op.alter_column(
+ with migration.remove_fks_from_table(TABLE_NAME):
+ # DB2 doesn't support nullable column in primary key
+ if context.bind.dialect.name == 'ibm_db_sa':
+ op.alter_column(
+ table_name=TABLE_NAME,
+ column_name='router_id',
+ nullable=False
+ )
+ op.alter_column(
+ table_name=TABLE_NAME,
+ column_name='l3_agent_id',
+ nullable=False
+ )
+
+ op.create_primary_key(
+ name=PK_NAME,
table_name=TABLE_NAME,
- column_name='l3_agent_id',
- nullable=False
+ cols=['router_id', 'l3_agent_id']
)
- op.create_primary_key(
- name=PK_NAME,
- table_name=TABLE_NAME,
- cols=['router_id', 'l3_agent_id']
- )
-
def downgrade():
context = op.get_context()
dialect = context.bind.dialect.name
- # Drop the existed foreign key constraints
- # In order to perform primary key changes
- db2fks = {}
- if dialect == 'ibm_db_sa':
- # NOTE(mriedem): In DB2 the foreign key names are randomly generated
- # if you didn't originally explicitly name them, so the name is like
- # SQLxxxxx where the suffix is a random integer. Therefore we go
- # through and just drop all of the foreign keys and save them so we
- # can re-create them later after the primary key is dropped.
- inspector = reflection.Inspector.from_engine(op.get_bind().engine)
- db2fks = inspector.get_foreign_keys(TABLE_NAME)
- for fk in db2fks:
- op.drop_constraint(
- name=fk.get('name'),
- table_name=TABLE_NAME,
- type_='foreignkey'
- )
- else:
- op.drop_constraint(
- name=fk_names[dialect]['l3_agent_id'],
- table_name=TABLE_NAME,
- type_='foreignkey'
- )
- op.drop_constraint(
- name=fk_names[dialect]['router_id'],
- table_name=TABLE_NAME,
- type_='foreignkey'
- )
-
op.drop_constraint(
name=PK_NAME,
table_name=TABLE_NAME,
nullable=False
)
- op.create_primary_key(
- name=PK_NAME,
- table_name=TABLE_NAME,
- cols=['id']
- )
-
- # Restore the foreign key constraints
- if dialect == 'ibm_db_sa':
- for fk in db2fks:
- op.create_foreign_key(
- name=fk.get('name'),
- source=TABLE_NAME,
- referent=fk.get('referred_table'),
- local_cols=fk.get('constrained_columns'),
- remote_cols=fk.get('referred_columns'),
- ondelete='CASCADE'
- )
- else:
- op.create_foreign_key(
- name=fk_names[dialect]['router_id'],
- source=TABLE_NAME,
- referent='routers',
- local_cols=['router_id'],
- remote_cols=['id'],
- ondelete='CASCADE'
- )
-
- op.create_foreign_key(
- name=fk_names[dialect]['l3_agent_id'],
- source=TABLE_NAME,
- referent='agents',
- local_cols=['l3_agent_id'],
- remote_cols=['id'],
- ondelete='CASCADE'
+ with migration.remove_fks_from_table(TABLE_NAME):
+ op.create_primary_key(
+ name=PK_NAME,
+ table_name=TABLE_NAME,
+ cols=['id']
)