]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fixes: #5661 - Correct reflection for composite primary keys in MSSQL
authorfulpm <8397318+fulpm@users.noreply.github.com>
Tue, 20 Oct 2020 20:50:16 +0000 (16:50 -0400)
committerfulpm <8397318+fulpm@users.noreply.github.com>
Tue, 20 Oct 2020 20:50:16 +0000 (16:50 -0400)
lib/sqlalchemy/dialects/mssql/base.py
test/dialect/mssql/test_reflection.py

index c8f2b4ca3b30b826623d6e06b8a753e6ccc5587b..0d4bb5a4c63e456b8644aa7a794daea529d51762 100644 (file)
@@ -3177,7 +3177,7 @@ class MSDialect(default.DefaultDialect):
                 C.c.table_name == tablename,
                 C.c.table_schema == owner,
             ),
-        )
+        ).order_by(TC.c.constraint_name, C.c.ordinal_position)
         c = connection.execution_options(future_result=True).execute(s)
         constraint_name = None
         for row in c.mappings():
index d791e9ec141f264336461e79f0a83488dc27022a..edd61fdb3df6d6d7ae54b56e942fcd9b9ae3564f 100644 (file)
@@ -7,6 +7,7 @@ from sqlalchemy import DDL
 from sqlalchemy import event
 from sqlalchemy import exc
 from sqlalchemy import ForeignKey
+from sqlalchemy import ForeignKeyConstraint
 from sqlalchemy import Identity
 from sqlalchemy import Index
 from sqlalchemy import inspect
@@ -241,6 +242,63 @@ class ReflectionTest(fixtures.TestBase, ComparesTables, AssertsCompiledSQL):
             ],
         )
 
+    @testing.provide_metadata
+    def test_pk_fk_column_order(self):
+        # test for issue #5661
+        metadata = self.metadata
+
+        Table(
+            "primary",
+            metadata,
+            Column("id", Integer),
+            Column("attr", Integer),
+            Column("name", types.VARCHAR(20)),
+            PrimaryKeyConstraint("name", "id", "attr", name="primary_pk"),
+            schema=testing.config.test_schema,
+        )
+
+        Table(
+            "foreign",
+            metadata,
+            Column("id", Integer, primary_key=True),
+            Column("pid", Integer),
+            Column("pattr", Integer),
+            Column("pname", types.VARCHAR(20)),
+            ForeignKeyConstraint(
+                ["pname", "pid", "pattr"],
+                [
+                    "%s.primary.name" % testing.config.test_schema,
+                    "%s.primary.id" % testing.config.test_schema,
+                    "%s.primary.attr" % testing.config.test_schema
+                ],
+                name="fk_primary_name_id_attr",
+            ),
+            schema=testing.config.test_schema,
+        )
+
+        metadata.create_all()
+
+        insp = inspect(testing.db)
+        eq_(
+            insp.get_pk_constraint("primary", testing.config.test_schema),
+            {
+                "name": "primary_pk",
+                "constrained_columns": ["name", "id", "attr"],
+            },
+        )
+        eq_(
+            insp.get_foreign_keys("foreign", testing.config.test_schema),
+            [
+                {
+                    "name": "fk_primary_name_id_attr",
+                    "constrained_columns": ["pname", "pid", "pattr"],
+                    "referred_schema": "test_schema",
+                    "referred_table": "primary",
+                    "referred_columns": ["name", "id", "attr"],
+                }
+            ],
+        )
+
     @testing.provide_metadata
     def test_table_name_that_is_greater_than_16_chars(self):
         metadata = self.metadata