]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Skip UniqueConstraint marked by unique=True in tometadata
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 2 Jun 2016 17:52:27 +0000 (13:52 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 2 Jun 2016 17:54:38 +0000 (13:54 -0400)
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
(cherry picked from commit afb466fb8bd9c2f8709e79fd0fce422b83ff1d6b)

doc/build/changelog/changelog_10.rst
lib/sqlalchemy/sql/schema.py
test/sql/test_metadata.py

index 5f9521c4792778beaedb569afbf499ea3427b7e2..b59ab392e548707fe34e0fedacdf99aca1cef770 100644 (file)
 .. 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
index f18102e05f115a945cf814eb30c2faea15df9e4a..f9c6d05a91e934d6faa382f6c2ffc26ba1186614 100644 (file)
@@ -862,8 +862,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:
index 1a4988aca52edd340de74551ca064fe0ab10a24d..ed014af3e27cedecd7d586d311273617db017aec 100644 (file)
@@ -1111,6 +1111,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):