From: Mike Bayer Date: Thu, 2 Jun 2016 17:52:27 +0000 (-0400) Subject: Skip UniqueConstraint marked by unique=True in tometadata X-Git-Tag: rel_1_1_0b1~31^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=afb466fb8bd9c2f8709e79fd0fce422b83ff1d6b;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Skip UniqueConstraint marked by unique=True in tometadata Fixes an issue where a Column would be copied with unique=True and at the same time the UniqueConstraint would also be copied, leading to duplicate UniqueConstraints in the target table, when tometadata() is used. Imitates the same logic used by index=True/Index to avoid duplicates. For some reason a fix was implemented for Index long ago but never for UniqueConstraint. Change-Id: Ie622ee912a6fb8bf0ea900a8b09d78c7ebc79fc0 Fixes: #3721 --- diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 5f9521c479..b59ab392e5 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -18,6 +18,14 @@ .. changelog:: :version: 1.0.14 + .. change:: + :tags: bug, sql + :tickets: 3721 + + Fixed bug whereby :meth:`.Table.tometadata` would make a duplicate + :class:`.UniqueConstraint` for each :class:`.Column` object that + featured the ``unique=True`` parameter. + .. change:: :tags: bug, engine, postgresql :tickets: 3716 diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index 64692644cf..cb01a49e36 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -852,8 +852,14 @@ class Table(DialectKWArgs, SchemaItem, TableClause): schema if referred_schema == self.schema else None) table.append_constraint( c.copy(schema=fk_constraint_schema, target_table=table)) - elif not c._type_bound: + # skip unique constraints that would be generated + # by the 'unique' flag on Column + if isinstance(c, UniqueConstraint) and \ + len(c.columns) == 1 and \ + list(c.columns)[0].unique: + continue + table.append_constraint( c.copy(schema=schema, target_table=table)) for index in self.indexes: diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py index 449956fcd4..344cfefa5e 100644 --- a/test/sql/test_metadata.py +++ b/test/sql/test_metadata.py @@ -1113,6 +1113,34 @@ class ToMetaDataTest(fixtures.TestBase, ComparesTables): eq_(str(table_c.join(table2_c).onclause), 'mytable.myid = othertable.myid') + def test_unique_true_flag(self): + meta = MetaData() + + table = Table('mytable', meta, Column('x', Integer, unique=True)) + + m2 = MetaData() + + t2 = table.tometadata(m2) + + eq_( + len([ + const for const + in t2.constraints + if isinstance(const, UniqueConstraint)]), + 1 + ) + + def test_index_true_flag(self): + meta = MetaData() + + table = Table('mytable', meta, Column('x', Integer, index=True)) + + m2 = MetaData() + + t2 = table.tometadata(m2) + + eq_(len(t2.indexes), 1) + class InfoTest(fixtures.TestBase): def test_metadata_info(self):