]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Reflect included columns as dialect_options
authorGord Thompson <gord@gordthompson.com>
Mon, 20 Dec 2021 21:37:13 +0000 (14:37 -0700)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 27 Dec 2021 19:32:39 +0000 (14:32 -0500)
Fixed reflection of covering indexes to report ``include_columns`` as part
of the ``dialect_options`` entry in the reflected index dictionary, thereby
enabling round trips from reflection->create to be complete. Included
columns continue to also be present under the ``include_columns`` key for
backwards compatibility.

Fixes: #7382
Change-Id: I4f16b65caed3a36d405481690a3a92432b5efd62

doc/build/changelog/unreleased_14/7382.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mssql/base.py
lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/testing/suite/test_reflection.py
test/dialect/postgresql/test_reflection.py

diff --git a/doc/build/changelog/unreleased_14/7382.rst b/doc/build/changelog/unreleased_14/7382.rst
new file mode 100644 (file)
index 0000000..db6ae45
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: bug, reflection, postgresql, mssql
+    :tickets: 7382
+
+    Fixed reflection of covering indexes to report ``include_columns`` as part
+    of the ``dialect_options`` entry in the reflected index dictionary, thereby
+    enabling round trips from reflection->create to be complete. Included
+    columns continue to also be present under the ``include_columns`` key for
+    backwards compatibility.
index 5b38c4bb51f5264f9fb0df835a1e72135608ff5f..03ab9e85e47144290191251495d5f9719f356b45 100644 (file)
@@ -3050,6 +3050,12 @@ class MSDialect(default.DefaultDialect):
                     indexes[row["index_id"]]["column_names"].append(
                         row["name"]
                     )
+        for index_info in indexes.values():
+            # NOTE: "root level" include_columns is legacy, now part of
+            #       dialect_options (issue #7382)
+            index_info.setdefault("dialect_options", {})[
+                "mssql_include"
+            ] = index_info["include_columns"]
 
         return list(indexes.values())
 
index 614c84b56e6640525f82ef3cd5066781cd80c55e..869e48bd4142c16d5d1f96ba46de1493f2a404ad 100644 (file)
@@ -4242,6 +4242,8 @@ class PGDialect(default.DefaultDialect):
                 "column_names": [idx["cols"][i] for i in idx["key"]],
             }
             if self.server_version_info >= (11, 0):
+                # NOTE: this is legacy, this is part of dialect_options now
+                # as of #7382
                 entry["include_columns"] = [idx["cols"][i] for i in idx["inc"]]
             if "duplicates_constraint" in idx:
                 entry["duplicates_constraint"] = idx["duplicates_constraint"]
@@ -4250,6 +4252,10 @@ class PGDialect(default.DefaultDialect):
                     (idx["cols"][idx["key"][i]], value)
                     for i, value in idx["sorting"].items()
                 )
+            if "include_columns" in entry:
+                entry.setdefault("dialect_options", {})[
+                    "postgresql_include"
+                ] = entry["include_columns"]
             if "options" in idx:
                 entry.setdefault("dialect_options", {})[
                     "postgresql_with"
index ba176bcd91728f0b596d96989f5f319b926104d4..9287f76dec36bbd6cd6ae0da18336bdcdc483dbc 100644 (file)
@@ -1232,6 +1232,9 @@ class ComponentReflectionTestExtra(fixtures.TestBase):
         ]
         if testing.requires.index_reflects_included_columns.enabled:
             expected[0]["include_columns"] = []
+            expected[0]["dialect_options"] = {
+                "%s_include" % connection.engine.name: []
+            }
 
         with expect_warnings(
             "Skipped unsupported reflection of expression-based index t_idx"
@@ -1264,10 +1267,21 @@ class ComponentReflectionTestExtra(fixtures.TestBase):
                     "column_names": ["x"],
                     "include_columns": ["y"],
                     "unique": False,
+                    "dialect_options": {
+                        "%s_include" % connection.engine.name: ["y"]
+                    },
                 }
             ],
         )
 
+        t2 = Table("t", MetaData(), autoload_with=connection)
+        eq_(
+            list(t2.indexes)[0].dialect_options[connection.engine.name][
+                "include"
+            ],
+            ["y"],
+        )
+
     def _type_round_trip(self, connection, metadata, *types):
         t = Table(
             "t",
index 2bfce557fe876a130dde7710ba7169a364f31d04..0e8a18c0fcf54240aae0df0ae4aa588371df87a4 100644 (file)
@@ -183,6 +183,7 @@ class PartitionedReflectionTest(fixtures.TablesTest, AssertsExecutionResults):
                     "unique": False,
                     "column_names": ["q"],
                     "include_columns": [],
+                    "dialect_options": {"postgresql_include": []},
                 }
             ],
         )
@@ -198,6 +199,7 @@ class PartitionedReflectionTest(fixtures.TablesTest, AssertsExecutionResults):
                 {
                     "column_names": ["q"],
                     "include_columns": [],
+                    "dialect_options": {"postgresql_include": []},
                     "name": mock.ANY,
                     "unique": False,
                 }
@@ -1131,6 +1133,7 @@ class ReflectionTest(
         expected = [{"name": "idx1", "unique": False, "column_names": ["y"]}]
         if testing.requires.index_reflects_included_columns.enabled:
             expected[0]["include_columns"] = []
+            expected[0]["dialect_options"] = {"postgresql_include": []}
 
         eq_(ind, expected)
 
@@ -1163,6 +1166,7 @@ class ReflectionTest(
         ]
         if testing.requires.index_reflects_included_columns.enabled:
             expected[0]["include_columns"] = []
+            expected[0]["dialect_options"]["postgresql_include"] = []
         eq_(ind, expected)
 
         m = MetaData()
@@ -1195,6 +1199,7 @@ class ReflectionTest(
         ]
         if testing.requires.index_reflects_included_columns.enabled:
             expected[0]["include_columns"] = []
+            expected[0]["dialect_options"]["postgresql_include"] = []
         eq_(ind, expected)
         m = MetaData()
         t1 = Table("t", m, autoload_with=connection)
@@ -1229,6 +1234,7 @@ class ReflectionTest(
                     "unique": False,
                     "column_names": ["x"],
                     "include_columns": ["name"],
+                    "dialect_options": {"postgresql_include": ["name"]},
                     "name": "idx1",
                 }
             ],
@@ -1604,6 +1610,7 @@ class ReflectionTest(
         ]
         if testing.requires.index_reflects_included_columns.enabled:
             expected[0]["include_columns"] = []
+            expected[0]["dialect_options"]["postgresql_include"] = []
 
         eq_(insp.get_indexes("t"), expected)