summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Harris <rconradharris@gmail.com>2013-02-21 23:00:50 +0000
committerRick Harris <rconradharris@gmail.com>2013-02-21 23:00:50 +0000
commite9d893a69cfdc6af8ec9a06bbd94ca6fed1eb09c (patch)
tree361ec079769fb7d842cbb973f76b9cb32172157e
parent09a8d250585a42acdf63a715065f920f52e5c6a0 (diff)
downloadnova-e9d893a69cfdc6af8ec9a06bbd94ca6fed1eb09c.tar.gz
nova-e9d893a69cfdc6af8ec9a06bbd94ca6fed1eb09c.tar.xz
nova-e9d893a69cfdc6af8ec9a06bbd94ca6fed1eb09c.zip
Migration 144: Fix drop index statement
When dropping an index related to a column, we need to make sure that the `Index` object is removed the `Table` object, otherwise a subsequent `drop_column` call to that same column will error out as it tries to re-drop the index. Change-Id: Ie6533b011ead1bc5dd2542041d50eb82e5654a55
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py52
1 files changed, 30 insertions, 22 deletions
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py b/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py
index 97b0f7bb0..692f9599b 100644
--- a/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py
+++ b/nova/db/sqlalchemy/migrate_repo/versions/144_add_node_to_migrations.py
@@ -1,4 +1,4 @@
-# Copyright 2012 OpenSmigrations.ck LLC.
+# Copyright 2012 Openstack LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
@@ -16,6 +16,29 @@ from sqlalchemy import and_, Index, String, Column, MetaData, Table
from sqlalchemy.sql.expression import select, update
+def _drop_index(engine, table, idx_name):
+ """Drop index from DB and remove index from SQLAlchemy table metadata.
+
+ idx.drop() in SQLAlchemy will issue a DROP INDEX statement to the DB but
+ WILL NOT update the table metadata to remove the `Index` object.
+
+ This can cause subsequent drop column calls on a related column to fail
+ because `drop_column` will see an `Index` object that isn't there, thus
+ issuing an erroneous second DROP INDEX call.
+
+ The solution is to update the table metadata to reflect the now dropped
+ column.
+ """
+ for idx in getattr(table, 'indexes'):
+ if idx.name == idx_name:
+ break
+ else:
+ raise Exception("Index '%s' not found!" % idx_name)
+
+ idx.drop(engine)
+ table.indexes.remove(idx)
+
+
def upgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
@@ -52,15 +75,14 @@ def downgrade(migrate_engine):
migrations = Table('migrations', meta, autoload=True)
- # drop new columns:
- source_node = Column('source_node', String(length=255))
- migrations.drop_column(source_node)
+ # drop new index:
+ _drop_index(migrate_engine, migrations,
+ 'migrations_by_host_nodes_and_status_idx')
- dest_node = Column('dest_node', String(length=255))
- migrations.drop_column(dest_node)
+ # drop new columns:
+ migrations.drop_column('source_node')
- # drop new index:
- _drop_new_index(migrations, migrate_engine)
+ migrations.drop_column('dest_node')
# re-add old index:
i = _old_index(migrations)
@@ -110,20 +132,6 @@ def _add_new_index(migrations, migrate_engine):
i.create(migrate_engine)
-def _drop_new_index(migrations, migrate_engine):
- if migrate_engine.name == "mysql":
- sql = ("drop index migrations_by_host_nodes_and_status_idx on "
- "migrations")
- migrate_engine.execute(sql)
-
- else:
- i = Index('migrations_by_host_nodes_and_status_idx',
- migrations.c.deleted, migrations.c.source_compute,
- migrations.c.dest_compute, migrations.c.source_node,
- migrations.c.dest_node, migrations.c.status)
- i.drop(migrate_engine)
-
-
def _old_index(migrations):
i = Index('migrations_by_host_and_status_idx', migrations.c.deleted,
migrations.c.source_compute, migrations.c.dest_compute,