From: Mike Bayer Date: Sat, 1 Nov 2025 02:35:49 +0000 (-0400) Subject: add test for issue 1743 X-Git-Tag: rel_1_17_2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80c95fe17dde88e17686b7e199f2c0aafc734177;p=thirdparty%2Fsqlalchemy%2Falembic.git add test for issue 1743 however this issue looks to be simple sqlite reflection issue on sqlalchemy side also fixes the incorrect exclusions code from 20c108720d7127ca. just skip entire test if SQLite fk reflection is not there. this exclusion should not have been added originally, it looks like this was mistaken for a limitation when it really was a bug in sqlite reflection Change-Id: I3f51ebaf01f41dba86cea0aa31be28334401887b --- diff --git a/alembic/testing/requirements.py b/alembic/testing/requirements.py index 7ec026b4..1b217c93 100644 --- a/alembic/testing/requirements.py +++ b/alembic/testing/requirements.py @@ -164,6 +164,10 @@ class SuiteRequirements(Requirements): @property def fk_names(self): + return self.foreign_key_name_reflection + + @property + def foreign_key_name_reflection(self): return exclusions.open() @property diff --git a/alembic/testing/suite/test_autogen_fks.py b/alembic/testing/suite/test_autogen_fks.py index 355e244c..d69736e6 100644 --- a/alembic/testing/suite/test_autogen_fks.py +++ b/alembic/testing/suite/test_autogen_fks.py @@ -199,7 +199,7 @@ class AutogenerateForeignKeysTest(AutogenFixtureTest, TestBase): eq_(diffs, []) - @config.requirements.fk_names + @config.requirements.foreign_key_name_reflection def test_casing_convention_changed_so_put_drops_first(self): m1 = MetaData() m2 = MetaData() diff --git a/tests/requirements.py b/tests/requirements.py index b8c8a680..081e5f85 100644 --- a/tests/requirements.py +++ b/tests/requirements.py @@ -61,13 +61,14 @@ class DefaultRequirements(SuiteRequirements): return exclusions.only_on(["sqlite"]) @property - def fk_names(self): + def foreign_key_name_reflection(self): """backend can reflect foreign key names""" # issue here was fixed in SQLAlchemy #12954 for sqlite, 2.0 # release - return exclusions.fails_if( - lambda config: not sqla_compat.sqla_2 and config.against("sqlite") + return exclusions.skip_if( + lambda config: not sqla_compat.sqla_2 + and exclusions.against(config, "sqlite") ) @property diff --git a/tests/test_autogen_diffs.py b/tests/test_autogen_diffs.py index 174cfac5..cd9d54ae 100644 --- a/tests/test_autogen_diffs.py +++ b/tests/test_autogen_diffs.py @@ -1910,3 +1910,98 @@ class MultipleMetaDataTest(AutogenFixtureTest, TestBase): [m1a, m1b], [m2a, m2b], ) + + +class AutogenFKTest(AutogenFixtureTest, TestBase): + """Test foreign key constraint handling in autogenerate.""" + + __backend__ = True + __requires__ = ("foreign_key_constraint_reflection",) + + @testing.variation("case", ["uppercase", "lowercase"]) + @testing.variation("use_naming_convention", [True, False]) + @config.requirements.foreign_key_name_reflection + def test_drop_fk_with_mixed_case_name(self, case, use_naming_convention): + """Test #1743""" + if case.uppercase: + fk_pattern = ( + "FK_%(table_name)s_%(column_0_name)s_%(referred_table_name)s" + ) + expected_name = "FK_child_parent_id_parent" + else: + fk_pattern = ( + "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s" + ) + expected_name = "fk_child_parent_id_parent" + + if use_naming_convention: + m1 = MetaData(naming_convention={"fk": fk_pattern}) + else: + m1 = MetaData() + + Table( + "parent", + m1, + Column("id", Integer, primary_key=True), + Column("name", String(50)), + ) + + c = Table( + "child", + m1, + Column("id", Integer, primary_key=True), + Column("name", String(50)), + Column("parent_id", Integer), + ( + ForeignKeyConstraint(["parent_id"], ["parent.id"]) + if use_naming_convention + else ForeignKeyConstraint( + ["parent_id"], ["parent.id"], name=expected_name + ) + ), + ) + + eq_( + [ + fk + for fk in c.constraints + if isinstance(fk, ForeignKeyConstraint) + ][0].name, + expected_name, + ) + + if use_naming_convention: + m2 = MetaData(naming_convention={"fk": fk_pattern}) + else: + m2 = MetaData() + + Table( + "parent", + m2, + Column("id", Integer, primary_key=True), + Column("name", String(50)), + ) + + Table( + "child", + m2, + Column("id", Integer, primary_key=True), + Column("name", String(50)), + Column("parent_id", Integer), + ) + + diffs = self._fixture(m1, m2) + + # Should detect the FK removal + eq_(len(diffs), 1, f"Expected 1 diff, got {len(diffs)}: {diffs}") + + # Verify it's a remove_fk operation with the correct name + self._assert_fk_diff( + diffs[0], + "remove_fk", + "child", + ["parent_id"], + "parent", + ["id"], + name=expected_name, + )