]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- Liberalized even more the check for MySQL indexes that shouldn't be
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 5 Jun 2014 20:22:14 +0000 (16:22 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 5 Jun 2014 20:22:14 +0000 (16:22 -0400)
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

alembic/ddl/mysql.py
docs/build/changelog.rst
tests/__init__.py
tests/test_autogen_indexes.py

index 96f42f382d97e602f22fcb1113185859ced6fda1..58d5c705b6ff797311acbdd18ff15b9bd7246699 100644 (file)
@@ -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
index 1a00cbcbb886b6e0d0229f799e919db434c7b6bf..89d945e007d0bf79bd0a11575eb1d91502eb6b6d 100644 (file)
@@ -5,6 +5,16 @@ Changelog
 .. 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
index cfb90983713645c61206f02827e30b718c51d4fb..85ea5b3255f3e68d74f510f539e3b9d5c99d697b 100644 (file)
@@ -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:
index e9d932112d73d59a6e0541a38034806b5d3d9d90..2f7a4a1c4b3c0543350d2e8c6ff4bb7c71739137 100644 (file)
@@ -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):