summaryrefslogtreecommitdiff
path: root/alembic
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-02-20 19:20:53 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2015-02-20 19:20:53 -0500
commit2108076362cc76130ae61e14c7a0120a1f0a59c8 (patch)
treef647c743f0ef91f5969915948bd004dfa5e43f39 /alembic
parente8a0c740b17100e6e366a7484d58d5b26f68c094 (diff)
downloadalembic-2108076362cc76130ae61e14c7a0120a1f0a59c8.tar.gz
- Fixed bug where MySQL backend would report dropped unique indexes
and/or constraints as both at the same time. This is because MySQL doesn't actually have a "unique constraint" construct that reports differently than a "unique index", so it is present in both lists. The net effect though is that the MySQL backend will report a dropped unique index/constraint as an index in cases where the object was first created as a unique constraint, if no other information is available to make the decision. This differs from other backends like Postgresql which can report on unique constraints and unique indexes separately. fixes #276
Diffstat (limited to 'alembic')
-rw-r--r--alembic/ddl/mysql.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/alembic/ddl/mysql.py b/alembic/ddl/mysql.py
index 8be4543..7956185 100644
--- a/alembic/ddl/mysql.py
+++ b/alembic/ddl/mysql.py
@@ -9,6 +9,7 @@ from .base import ColumnNullable, ColumnName, ColumnDefault, \
ColumnType, AlterColumn, format_column_name, \
format_server_default
from .base import alter_table
+from ..autogenerate import compare
class MySQLImpl(DefaultImpl):
@@ -123,6 +124,39 @@ class MySQLImpl(DefaultImpl):
if idx.name in removed:
metadata_indexes.remove(idx)
+ # then dedupe unique indexes vs. constraints, since MySQL
+ # doesn't really have unique constraints as a separate construct.
+ # but look in the metadata and try to maintain constructs
+ # that already seem to be defined one way or the other
+ # on that side. See #276
+ metadata_uq_names = set([
+ cons.name for cons in metadata_unique_constraints
+ if cons.name is not None])
+
+ unnamed_metadata_uqs = set([
+ compare._uq_constraint_sig(cons).sig
+ for cons in metadata_unique_constraints
+ if cons.name is None
+ ])
+
+ metadata_ix_names = set([
+ cons.name for cons in metadata_indexes if cons.unique])
+ conn_uq_names = dict(
+ (cons.name, cons) for cons in conn_unique_constraints
+ )
+ conn_ix_names = dict(
+ (cons.name, cons) for cons in conn_indexes if cons.unique
+ )
+
+ for overlap in set(conn_uq_names).intersection(conn_ix_names):
+ if overlap not in metadata_uq_names:
+ if compare._uq_constraint_sig(conn_uq_names[overlap]).sig \
+ not in unnamed_metadata_uqs:
+
+ conn_unique_constraints.discard(conn_uq_names[overlap])
+ elif overlap not in metadata_ix_names:
+ conn_indexes.discard(conn_ix_names[overlap])
+
class MySQLAlterDefault(AlterColumn):