SQLAlchemy 2.0 Dokumentation
SQLAlchemy ORM
- ORM Schnellstart
- ORM Abgebildete Klassenkonfiguration
- Beziehungskonfiguration
- Grundlegende Beziehungsmuster
- Adjazenzlisten-Beziehungen
- Konfiguration, wie Beziehungen verknüpft werden
- Arbeiten mit großen Sammlungen
- Sammlungsanpassung und API-Details
- Spezielle Beziehungspersistenzmuster
- Verwendung des Legacy-Parameters 'backref' für Beziehungen¶
- Beziehungs-API
- ORM Abfragehandbuch
- Verwendung der Sitzung
- Ereignisse und Interna
- ORM Erweiterungen
- ORM Beispiele
Projektversionen
Verwendung des Legacy-Parameters 'backref' für Beziehungen¶
Hinweis
Das Schlüsselwort relationship.backref sollte als Legacy betrachtet werden, und die Verwendung von relationship.back_populates mit expliziten relationship()-Konstrukten wird bevorzugt. Die Verwendung einzelner relationship()-Konstrukte bietet Vorteile, darunter, dass beide ORM-gemappten Klassen ihre Attribute sofort beim Erstellen der Klasse enthalten, anstatt als verzögerter Schritt, und die Konfiguration ist einfacher, da alle Argumente explizit sind. Neue PEP 484-Funktionen in SQLAlchemy 2.0 nutzen ebenfalls die Tatsache aus, dass Attribute explizit im Quellcode vorhanden sind, anstatt dynamische Attributerzeugung zu verwenden.
Siehe auch
Allgemeine Informationen zu bidirektionalen Beziehungen finden Sie in den folgenden Abschnitten
Arbeiten mit ORM-verknüpften Objekten - im SQLAlchemy Unified Tutorial, wird eine Übersicht über die Konfiguration und das Verhalten bidirektionaler Beziehungen mithilfe von relationship.back_populates präsentiert.
Verhalten von save-update Cascade bei bidirektionalen Beziehungen - Hinweise zum Verhalten von bidirektionalen relationship()-Beziehungen in Bezug auf Session-Kaskadenverhalten.
Das Schlüsselwortargument relationship.backref im Konstrukt relationship() ermöglicht die automatische Generierung einer neuen relationship(), die automatisch zur ORM-Zuordnung der zugehörigen Klasse hinzugefügt wird. Diese wird dann in eine relationship.back_populates-Konfiguration gegen die aktuell konfigurierte relationship() eingefügt, wobei beide relationship()-Konstrukte aufeinander verweisen.
Ausgehend vom folgenden Beispiel
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import DeclarativeBase, relationship
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "user"
id = mapped_column(Integer, primary_key=True)
name = mapped_column(String)
addresses = relationship("Address", backref="user")
class Address(Base):
__tablename__ = "address"
id = mapped_column(Integer, primary_key=True)
email = mapped_column(String)
user_id = mapped_column(Integer, ForeignKey("user.id"))Die obige Konfiguration erstellt eine Sammlung von Address-Objekten auf User mit dem Namen User.addresses. Sie erstellt auch ein Attribut .user auf Address, das auf das übergeordnete User-Objekt verweist. Die Verwendung von relationship.back_populates ist äquivalent zu Folgendem
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import DeclarativeBase, relationship
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "user"
id = mapped_column(Integer, primary_key=True)
name = mapped_column(String)
addresses = relationship("Address", back_populates="user")
class Address(Base):
__tablename__ = "address"
id = mapped_column(Integer, primary_key=True)
email = mapped_column(String)
user_id = mapped_column(Integer, ForeignKey("user.id"))
user = relationship("User", back_populates="addresses")Das Verhalten der Beziehungen User.addresses und Address.user ist, dass sie nun **bidirektional** funktionieren, was bedeutet, dass Änderungen auf einer Seite der Beziehung die andere Seite beeinflussen. Ein Beispiel und eine Diskussion dieses Verhaltens finden Sie im SQLAlchemy Unified Tutorial unter Arbeiten mit ORM-verknüpften Objekten.
Standardargumente für Backref¶
Da relationship.backref eine vollständige neue relationship() generiert, versucht der Generierungsprozess standardmäßig, entsprechende Argumente in der neuen relationship() zu berücksichtigen, die den ursprünglichen Argumenten entsprechen. Als Beispiel folgt hier eine relationship(), die eine benutzerdefinierte Join-Bedingung enthält und auch den Parameter relationship.backref enthält.
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import DeclarativeBase, relationship
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "user"
id = mapped_column(Integer, primary_key=True)
name = mapped_column(String)
addresses = relationship(
"Address",
primaryjoin=(
"and_(User.id==Address.user_id, Address.email.startswith('tony'))"
),
backref="user",
)
class Address(Base):
__tablename__ = "address"
id = mapped_column(Integer, primary_key=True)
email = mapped_column(String)
user_id = mapped_column(Integer, ForeignKey("user.id"))Wenn der „backref“ generiert wird, wird die relationship.primaryjoin-Bedingung auch in die neue relationship() kopiert.
>>> print(User.addresses.property.primaryjoin)
"user".id = address.user_id AND address.email LIKE :email_1 || '%%'
>>>
>>> print(Address.user.property.primaryjoin)
"user".id = address.user_id AND address.email LIKE :email_1 || '%%'
>>>Weitere übertragbare Argumente sind der Parameter relationship.secondary, der sich auf eine Many-to-Many-Assoziationstabelle bezieht, sowie die „Join“-Argumente relationship.primaryjoin und relationship.secondaryjoin; „backref“ ist intelligent genug, um zu erkennen, dass diese beiden Argumente auf der gegenüberliegenden Seite auch „umgekehrt“ werden müssen.
Argumente für Backref angeben¶
Viele andere Argumente für einen „backref“ sind nicht implizit und umfassen Argumente wie relationship.lazy, relationship.remote_side, relationship.cascade und relationship.cascade_backrefs. In diesem Fall verwenden wir die Funktion backref() anstelle eines Strings; dies speichert eine bestimmte Menge von Argumenten, die an die neue, generierte relationship() übertragen werden.
# <other imports>
from sqlalchemy.orm import backref
class User(Base):
__tablename__ = "user"
id = mapped_column(Integer, primary_key=True)
name = mapped_column(String)
addresses = relationship(
"Address",
backref=backref("user", lazy="joined"),
)Wo wir oben eine lazy="joined"-Direktive nur auf der Address.user-Seite platziert haben, was bedeutet, dass bei einer Abfrage gegen Address ein Join zur User-Entität automatisch erfolgen sollte, was das Attribut .user jedes zurückgegebenen Address füllt. Die Funktion backref() hat die von uns gegebenen Argumente in ein Format gebracht, das von der empfangenden relationship() als zusätzliche Argumente interpretiert wird, die auf die von ihr erstellte neue Beziehung angewendet werden sollen.
Die Designs von flambé! dem Drachen und Der Alchemist wurden von Rotem Yaari erstellt und großzügig gespendet.
Erstellt mit Sphinx 7.2.6. Dokumentation zuletzt generiert: Di 11 Mär 2025 14:40:17 EDT