]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
forwards port test cases and changelog for #7958 to 2.0
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 24 Apr 2022 20:19:16 +0000 (16:19 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 24 Apr 2022 20:42:52 +0000 (16:42 -0400)
in 6f02d5edd88fe2475629438b0730181a2b00c5fe some cleanup
to ForeignKey repaired the use case of ForeignKey objects
referring to table name alone, by adding more robust
column resolution logic.  This change also fixes an issue
where the "referred column" naming convention key uses the
resolved referred column earlier than usual when a
ForeignKey is setting up its constraint.

change message for 1.4:

Fixed bug where :class:`.ForeignKeyConstraint` naming conventions using the
``referred_column_0`` naming convention key would not work if the foreign
key constraint were set up as a :class:`.ForeignKey` object rather than an
explicit :class:`.ForeignKeyConstraint` object. As this change makes use of
a backport of some fixes from version 2.0, an additional little-known
feature that has likely been broken for many years is also fixed which is
that a :class:`.ForeignKey` object may refer to a referred table by name of
the table alone without using a column name, if the name of the referent
column is the same as that of the referred column.

The ``referred_column_0`` naming convention key was not previously not
tested with the :class:`.ForeignKey` object, only
:class:`.ForeignKeyConstraint`, and this bug reveals that the feature has
never worked correctly unless :class:`.ForeignKeyConstraint` is used for
all FK constraints. This bug traces back to the original introduction of
the feature introduced for :ticket:`3989`.

Fixes: #7958
Change-Id: I230d43e9deba5dff889b9e7fee6cd4d3aa2496d3
(cherry picked from commit e32937fa6a7dcc3d5087aa1f41049373ab9e4038)

doc/build/changelog/unreleased_14/7958.rst [new file with mode: 0644]
test/sql/test_metadata.py

diff --git a/doc/build/changelog/unreleased_14/7958.rst b/doc/build/changelog/unreleased_14/7958.rst
new file mode 100644 (file)
index 0000000..057647b
--- /dev/null
@@ -0,0 +1,20 @@
+.. change::
+    :tags: bug, schema
+    :tickets: 7958
+
+    Fixed bug where :class:`.ForeignKeyConstraint` naming conventions using the
+    ``referred_column_0`` naming convention key would not work if the foreign
+    key constraint were set up as a :class:`.ForeignKey` object rather than an
+    explicit :class:`.ForeignKeyConstraint` object. As this change makes use of
+    a backport of some fixes from version 2.0, an additional little-known
+    feature that has likely been broken for many years is also fixed which is
+    that a :class:`.ForeignKey` object may refer to a referred table by name of
+    the table alone without using a column name, if the name of the referent
+    column is the same as that of the referred column.
+
+    The ``referred_column_0`` naming convention key was not previously not
+    tested with the :class:`.ForeignKey` object, only
+    :class:`.ForeignKeyConstraint`, and this bug reveals that the feature has
+    never worked correctly unless :class:`.ForeignKeyConstraint` is used for
+    all FK constraints. This bug traces back to the original introduction of
+    the feature introduced for :ticket:`3989`.
index f7480d11a96a5cf7bbe5e21378b0980c4fdc0fc6..b175f96633e4ffe349a9af27d282b87802944a33 100644 (file)
@@ -5345,6 +5345,29 @@ class NamingConventionTest(fixtures.TestBase, AssertsCompiledSQL):
         a1.append_constraint(fk)
         eq_(fk.name, "fk_address_user_id_user_id")
 
+    @testing.combinations(True, False, argnames="col_has_type")
+    def test_fk_ref_local_referent_has_no_type(self, col_has_type):
+        """test #7958"""
+
+        metadata = MetaData(
+            naming_convention={
+                "fk": "fk_%(referred_column_0_name)s",
+            }
+        )
+        Table("a", metadata, Column("id", Integer, primary_key=True))
+        b = Table(
+            "b",
+            metadata,
+            Column("id", Integer, primary_key=True),
+            Column("aid", ForeignKey("a.id"))
+            if not col_has_type
+            else Column("aid", Integer, ForeignKey("a.id")),
+        )
+        fks = list(
+            c for c in b.constraints if isinstance(c, ForeignKeyConstraint)
+        )
+        eq_(fks[0].name, "fk_id")
+
     def test_custom(self):
         def key_hash(const, table):
             return "HASH_%s" % table.name