]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add unique_constraint_name to MSSQL FK reflection
authorSean Dunn <sean.dunn@ihsmarkit.com>
Fri, 29 Jun 2018 14:26:57 +0000 (10:26 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 29 Jun 2018 14:52:47 +0000 (10:52 -0400)
Fixed bug in MSSQL reflection where when two same-named tables in different
schemas had same-named primary key constraints, foreign key constraints
referring to one of the tables would have their columns doubled, causing
errors.   Pull request courtesy Sean Dunn.

Fixes: #4228
Change-Id: I7dabaaee0944e1030048826ba39fc574b0d63031
Pull-request: https://github.com/zzzeek/sqlalchemy/pull/457

doc/build/changelog/unreleased_12/4228.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mssql/base.py
lib/sqlalchemy/dialects/mssql/information_schema.py
lib/sqlalchemy/testing/provision.py
test/dialect/mssql/test_reflection.py

diff --git a/doc/build/changelog/unreleased_12/4228.rst b/doc/build/changelog/unreleased_12/4228.rst
new file mode 100644 (file)
index 0000000..c3a436d
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, mssql
+    :tickets: 4228
+
+    Fixed bug in MSSQL reflection where when two same-named tables in different
+    schemas had same-named primary key constraints, foreign key constraints
+    referring to one of the tables would have their columns doubled, causing
+    errors.   Pull request courtesy Sean Dunn.
index bc3905535e4da4b546e1d67ebf51f851ac8d481f..c10b75c02c4efbb5d75c569acfb07c2e45f503b8 100644 (file)
@@ -2251,6 +2251,8 @@ class MSDialect(default.DefaultDialect):
                                 C.c.constraint_name == RR.c.constraint_name,
                                 R.c.constraint_name ==
                                 RR.c.unique_constraint_name,
+                                R.c.constraint_schema ==
+                                RR.c.unique_constraint_schema,
                                 C.c.ordinal_position == R.c.ordinal_position
                                 ),
                        order_by=[RR.c.constraint_name, R.c.ordinal_position]
index 103458705708e58c9685a35a33c519891107d73c..3682fae481eb0fa085daebb642be3555151a92ee 100644 (file)
@@ -103,6 +103,8 @@ key_constraints = Table("KEY_COLUMN_USAGE", ischema,
                                key="column_name"),
                         Column("CONSTRAINT_NAME", CoerceUnicode,
                                key="constraint_name"),
+                        Column("CONSTRAINT_SCHEMA", CoerceUnicode,
+                               key="constraint_schema"),
                         Column("ORDINAL_POSITION", Integer,
                                key="ordinal_position"),
                         schema="INFORMATION_SCHEMA")
index 8abfa3301c9b786351b8daf96a3c74ebf552ab12..4c749d382da53552eb1c2518ecdaac630337f416 100644 (file)
@@ -369,6 +369,7 @@ def _mssql_create_db(cfg, eng, ident):
             "ALTER DATABASE %s SET READ_COMMITTED_SNAPSHOT ON" % ident)
         conn.execute("use %s" % ident)
         conn.execute("create schema test_schema")
+        conn.execute("create schema test_schema_2")
 
 
 @_drop_db.for_db("mssql")
index d3b270d2f572d73b8358e2df83f58f56cb04616e..720d6ec18f8c6b9737dc5d43bdc601056799fd5c 100644 (file)
@@ -118,6 +118,50 @@ class ReflectionTest(fixtures.TestBase, ComparesTables, AssertsCompiledSQL):
         assert isinstance(t1.c.id.type, Integer)
         assert isinstance(t1.c.data.type, types.NullType)
 
+    @testing.provide_metadata
+    def test_cross_schema_fk_pk_name_overlaps(self):
+        # test for issue #4228
+        metadata = self.metadata
+
+        Table(
+            "subject", metadata,
+            Column("id", Integer),
+            PrimaryKeyConstraint("id", name="subj_pk"),
+            schema=testing.config.test_schema,
+        )
+
+        Table(
+            "referrer", metadata,
+            Column("id", Integer, primary_key=True),
+            Column(
+                'sid',
+                ForeignKey(
+                    "%s.subject.id" % testing.config.test_schema,
+                    name='fk_subject')
+            ),
+            schema=testing.config.test_schema
+        )
+
+        Table(
+            "subject", metadata,
+            Column("id", Integer),
+            PrimaryKeyConstraint("id", name="subj_pk"),
+            schema=testing.config.test_schema_2
+        )
+
+        metadata.create_all()
+
+        insp = inspect(testing.db)
+        eq_(
+            insp.get_foreign_keys("referrer", testing.config.test_schema),
+            [{
+                'name': 'fk_subject',
+                'constrained_columns': ['sid'],
+                'referred_schema': 'test_schema',
+                'referred_table': 'subject',
+                'referred_columns': ['id']}]
+        )
+
     @testing.provide_metadata
     def test_db_qualified_items(self):
         metadata = self.metadata