diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-06-05 16:22:14 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-06-05 16:22:14 -0400 |
commit | 1f4d8c61033685d90c344c96222e2f8249ca68e8 (patch) | |
tree | 527f060c7b23227d157fbcafb5b6d5af1910bcd6 | |
parent | 0a93da93d011118d9446e0ef7b4d5d80e550adfb (diff) | |
download | alembic-1f4d8c61033685d90c344c96222e2f8249ca68e8.tar.gz |
- Liberalized even more the check for MySQL indexes that shouldn't be
counted in autogenerate as "drops"; this time it's been reported
that an implicitly created index might be named the same as a composite
foreign key constraint, and not the actual columns, so we now skip those
when detected as well. fixes #208
-rw-r--r-- | alembic/ddl/mysql.py | 17 | ||||
-rw-r--r-- | docs/build/changelog.rst | 10 | ||||
-rw-r--r-- | tests/__init__.py | 2 | ||||
-rw-r--r-- | tests/test_autogen_indexes.py | 58 |
4 files changed, 74 insertions, 13 deletions
diff --git a/alembic/ddl/mysql.py b/alembic/ddl/mysql.py index 96f42f3..58d5c70 100644 --- a/alembic/ddl/mysql.py +++ b/alembic/ddl/mysql.py @@ -78,10 +78,19 @@ class MySQLImpl(DefaultImpl): removed = set() for idx in list(conn_indexes): # MySQL puts implicit indexes on FK columns, even if - # composite and even if MyISAM, so can't check this too easily - if idx.name == idx.columns.keys()[0]: - conn_indexes.remove(idx) - removed.add(idx.name) + # composite and even if MyISAM, so can't check this too easily. + # the name of the index may be the column name or it may + # be the name of the FK constraint. + for col in idx.columns: + if idx.name == col.name: + conn_indexes.remove(idx) + removed.add(idx.name) + break + for fk in col.foreign_keys: + if fk.name == idx.name: + conn_indexes.remove(idx) + removed.add(idx.name) + break # then remove indexes from the "metadata_indexes" # that we've removed from reflected, otherwise they come out diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index 1a00cbc..89d945e 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -6,6 +6,16 @@ Changelog :version: 0.6.6 .. change:: + :tags: bug + :tickets: 208 + + Liberalized even more the check for MySQL indexes that shouldn't be + counted in autogenerate as "drops"; this time it's been reported + that an implicitly created index might be named the same as a composite + foreign key constraint, and not the actual columns, so we now skip those + when detected as well. + + .. change:: :tags: feature :pullreq: github:10 diff --git a/tests/__init__.py b/tests/__init__.py index cfb9098..85ea5b3 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -65,7 +65,7 @@ def db_for_dialect(name): except configparser.NoOptionError: raise SkipTest("No dialect %r in test.cfg" % name) try: - eng = create_engine(cfg) + eng = create_engine(cfg, echo='debug') except ImportError as er1: raise SkipTest("Can't import DBAPI: %s" % er1) try: diff --git a/tests/test_autogen_indexes.py b/tests/test_autogen_indexes.py index e9d9321..2f7a4a1 100644 --- a/tests/test_autogen_indexes.py +++ b/tests/test_autogen_indexes.py @@ -5,8 +5,9 @@ from sqlalchemy import MetaData, Column, Table, Integer, String, Text, \ Numeric, DATETIME, INTEGER, \ TypeDecorator, Unicode, Enum,\ UniqueConstraint, Boolean, \ - PrimaryKeyConstraint, Index, func, ForeignKeyConstraint - + PrimaryKeyConstraint, Index, func, ForeignKeyConstraint,\ + ForeignKey +from sqlalchemy.schema import AddConstraint from . import sqlite_db, eq_, db_for_dialect py3k = sys.version_info >= (3, ) @@ -190,31 +191,37 @@ class AutogenerateUniqueIndexTest(AutogenFixtureTest, TestCase): Table('nothing_changed', m1, Column('id1', Integer, primary_key=True), Column('id2', Integer, primary_key=True), - Column('x', String(20), unique=True) + Column('x', String(20), unique=True), + mysql_engine='InnoDB' ) Table('nothing_changed_related', m1, Column('id1', Integer), Column('id2', Integer), ForeignKeyConstraint(['id1', 'id2'], - ['nothing_changed.id1', 'nothing_changed.id2']) + ['nothing_changed.id1', 'nothing_changed.id2']), + mysql_engine='InnoDB' ) Table('nothing_changed', m2, Column('id1', Integer, primary_key=True), Column('id2', Integer, primary_key=True), - Column('x', String(20), unique=True) + Column('x', String(20), unique=True), + mysql_engine='InnoDB' ) Table('nothing_changed_related', m2, Column('id1', Integer), Column('id2', Integer), ForeignKeyConstraint(['id1', 'id2'], - ['nothing_changed.id1', 'nothing_changed.id2']) + ['nothing_changed.id1', 'nothing_changed.id2']), + mysql_engine='InnoDB' ) diffs = self._fixture(m1, m2) eq_(diffs, []) + + def test_nothing_changed_index_named_as_column(self): m1 = MetaData() m2 = MetaData() @@ -236,6 +243,36 @@ class AutogenerateUniqueIndexTest(AutogenFixtureTest, TestCase): diffs = self._fixture(m1, m2) eq_(diffs, []) + def test_nothing_changed_implicit_fk_index_named(self): + m1 = MetaData() + m2 = MetaData() + + Table("nothing_changed", m1, + Column('id', Integer, primary_key=True), + Column('other_id', + ForeignKey('nc2.id', + name='fk_my_table_other_table' + ), + nullable=False), + Column('foo', Integer), + mysql_engine='InnoDB') + Table('nc2', m1, + Column('id', Integer, primary_key=True), + mysql_engine='InnoDB') + + Table("nothing_changed", m2, + Column('id', Integer, primary_key=True), + Column('other_id', ForeignKey('nc2.id', + name='fk_my_table_other_table'), + nullable=False), + Column('foo', Integer), + mysql_engine='InnoDB') + Table('nc2', m2, + Column('id', Integer, primary_key=True), + mysql_engine='InnoDB') + diffs = self._fixture(m1, m2) + eq_(diffs, []) + def test_new_idx_index_named_as_column(self): m1 = MetaData() m2 = MetaData() @@ -472,8 +509,13 @@ class MySQLUniqueIndexTest(AutogenerateUniqueIndexTest): reports_unnamed_constraints = True def test_removed_idx_index_named_as_column(self): - # TODO: this should be an "assert fails" - pass + try: + super(MySQLUniqueIndexTest, + self).test_removed_idx_index_named_as_column() + except IndexError: + assert True + else: + assert False, "unexpected success" @classmethod def _get_bind(cls): |