]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Modernize Self-Referential example
authorFederico Caselli <cfederico87@gmail.com>
Tue, 18 Jul 2023 18:18:47 +0000 (20:18 +0200)
committerFederico Caselli <cfederico87@gmail.com>
Sat, 5 Aug 2023 09:51:53 +0000 (09:51 +0000)
References: #10115
Change-Id: Iee85b1277cdfee93ffb096df8ba85af48d09f1bc

doc/build/orm/join_conditions.rst
lib/sqlalchemy/util/langhelpers.py
test/base/test_utils.py

index 79c3e98adf7e68ed605b8ea88a1f32890ed84063..09c744e40a13873bd1f63715703469ae1d1ea789 100644 (file)
@@ -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
index 8314a36fc535053baa1abe7e44dafebcdb84be27..6c9afb5df62f11e08e4fea031d5cef4a705c7195 100644 (file)
@@ -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
index 91b58d171895229df379db14b3d5086030ea4580..7dcf0968a7cd29f1422989ecdfc1100c97fdca03 100644 (file)
@@ -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):