From: Federico Caselli Date: Tue, 18 Jul 2023 18:18:47 +0000 (+0200) Subject: Modernize Self-Referential example X-Git-Tag: rel_2_0_20~17^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27e80ff061ee82ca23437331ec4fbea51a1403cf;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Modernize Self-Referential example References: #10115 Change-Id: Iee85b1277cdfee93ffb096df8ba85af48d09f1bc --- diff --git a/doc/build/orm/join_conditions.rst b/doc/build/orm/join_conditions.rst index 79c3e98adf..09c744e40a 100644 --- a/doc/build/orm/join_conditions.rst +++ b/doc/build/orm/join_conditions.rst @@ -541,6 +541,8 @@ specifies a many-to-many reference using the :paramref:`_orm.relationship.second A common situation which involves the usage of :paramref:`_orm.relationship.primaryjoin` and :paramref:`_orm.relationship.secondaryjoin` is when establishing a many-to-many relationship from a class to itself, as shown below:: + from typing import List + from sqlalchemy import Integer, ForeignKey, String, Column, Table from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import relationship @@ -560,14 +562,21 @@ is when establishing a many-to-many relationship from a class to itself, as show class Node(Base): __tablename__ = "node" - id = mapped_column(Integer, primary_key=True) - label = mapped_column(String) - right_nodes = relationship( + id: Mapped[int] = mapped_column(primary_key=True) + label: Mapped[str] + right_nodes: Mapped[List["None"]] = relationship( "Node", secondary=node_to_node, primaryjoin=id == node_to_node.c.left_node_id, secondaryjoin=id == node_to_node.c.right_node_id, - backref="left_nodes", + back_populates="left_nodes", + ) + left_nodes: Mapped[List["None"]] = relationship( + "Node", + secondary=node_to_node, + primaryjoin=id == node_to_node.c.right_node_id, + secondaryjoin=id == node_to_node.c.left_node_id, + back_populates="right_nodes", ) Where above, SQLAlchemy can't know automatically which columns should connect diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 8314a36fc5..6c9afb5df6 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -1636,7 +1636,7 @@ class symbol(int): else: if canonical and canonical != sym: raise TypeError( - f"Can't replace canonical symbol for {name} " + f"Can't replace canonical symbol for {name!r} " f"with new int value {canonical}" ) return sym diff --git a/test/base/test_utils.py b/test/base/test_utils.py index 91b58d1718..7dcf0968a7 100644 --- a/test/base/test_utils.py +++ b/test/base/test_utils.py @@ -2530,7 +2530,8 @@ class SymbolTest(fixtures.TestBase): with expect_raises_message( TypeError, - "Can't replace canonical symbol for fi_sym1 with new int value 2", + "Can't replace canonical symbol for 'fi_sym1' " + "with new int value 2", ): class Enum2(FastIntFlag):