--- /dev/null
+.. 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.
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())
"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"]
(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"
]
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"
"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",
"unique": False,
"column_names": ["q"],
"include_columns": [],
+ "dialect_options": {"postgresql_include": []},
}
],
)
{
"column_names": ["q"],
"include_columns": [],
+ "dialect_options": {"postgresql_include": []},
"name": mock.ANY,
"unique": False,
}
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)
]
if testing.requires.index_reflects_included_columns.enabled:
expected[0]["include_columns"] = []
+ expected[0]["dialect_options"]["postgresql_include"] = []
eq_(ind, expected)
m = MetaData()
]
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)
"unique": False,
"column_names": ["x"],
"include_columns": ["name"],
+ "dialect_options": {"postgresql_include": ["name"]},
"name": "idx1",
}
],
]
if testing.requires.index_reflects_included_columns.enabled:
expected[0]["include_columns"] = []
+ expected[0]["dialect_options"]["postgresql_include"] = []
eq_(insp.get_indexes("t"), expected)