在 SQLAlchemy 中,relationship
是一個非常重要的函數,用于定義模型之間的關系。它用于在 ORM 層面上表示數據庫表之間的關聯關系(如 1 對 1、1 對多和多對多)。relationship
的主要作用是提供一個高級接口,用于在模型之間導航和操作關聯數據。
relationship
的基本用法
relationship
函數通常定義在模型類中,用于指定兩個模型之間的關系。它的基本語法如下:
Python復制
relationship(argument, secondary=None, primaryjoin=None, secondaryjoin=None, backref=None, back_populates=None, uselist=True, order_by=False, lazy='select', viewonly=False, ...)
關鍵參數詳解
1. argument
這是 relationship
函數的第一個位置參數,通常是一個字符串,表示目標模型的類名。例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child") # 指向 Child 模型
2. back_populates
用于雙向關系的設置。它指定在目標模型中,哪個字段會反向引用當前模型。back_populates
是 SQLAlchemy 1.0 之后推薦的雙向關系設置方式,替代了舊版本的 backref
。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", back_populates="parent")class Child(Base):__tablename__ = 'children'id = Column(Integer, primary_key=True)parent_id = Column(Integer, ForeignKey('parents.id'))parent = relationship("Parent", back_populates="children")
在上述代碼中,Parent
的 children
和 Child
的 parent
通過 back_populates
建立了雙向關系。
3. backref
backref
是一個較老的參數,用于在目標模型中自動創建一個反向引用字段。它是一個字符串,表示在目標模型中創建的字段名稱。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", backref="parent")
在 Child
模型中會自動創建一個名為 parent
的字段,指向 Parent
模型。
注意:backref
和 back_populates
是互斥的,不能同時使用。back_populates
是更推薦的方式,因為它更清晰地表達了雙向關系。
4. uselist
該參數用于指定關系是否為多對一或一對一。默認值為 True
,表示多對一或一對多關系。如果設置為 False
,則表示一對一關系。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)child = relationship("Child", uselist=False) # 一對一關系
5. secondary
用于多對多關系,指定關聯表。關聯表通常是一個 Table
對象,定義了兩個模型之間的多對多關系。
例如:
association_table = Table('association', Base.metadata,Column('parent_id', Integer, ForeignKey('parents.id')),Column('child_id', Integer, ForeignKey('children.id'))
)class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", secondary=association_table, back_populates="parents")class Child(Base):__tablename__ = 'children'id = Column(Integer, primary_key=True)parents = relationship("Parent", secondary=association_table, back_populates="children")
6. primaryjoin
和 secondaryjoin
這兩個參數用于顯式指定連接條件,通常在復雜的外鍵關系中使用。primaryjoin
指定主表的連接條件,secondaryjoin
指定目標表的連接條件。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", primaryjoin="Parent.id == Child.parent_id")class Child(Base):__tablename__ = 'children'id = Column(Integer, primary_key=True)parent_id = Column(Integer, ForeignKey('parents.id'))
7. lazy
該參數用于控制關聯對象的加載策略。常見值包括:
-
select
:默認值,表示在訪問關聯對象時,會自動執行一個 SELECT 查詢。 -
joined
:表示在加載主對象時,通過 JOIN 查詢同時加載關聯對象。 -
dynamic
:表示返回一個查詢對象,而不是直接加載關聯對象,適合處理大量關聯數據。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", lazy="joined") # 使用 JOIN 查詢加載關聯對象
8. order_by
用于指定關聯對象的排序方式。它接受一個列對象或字符串,表示排序的依據。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", order_by="Child.name") # 按照 Child 的 name 字段排序
9. viewonly
該參數用于創建只讀關系。如果設置為 True
,則不能通過該關系進行數據的添加、刪除或更新操作。
例如:
class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", viewonly=True) # 只讀關系
總結
relationship
是 SQLAlchemy 中用于定義模型關系的核心函數,通過合理使用其參數,可以靈活地實現各種復雜的關系(如 1 對 1、1 對多和多對多)。以下是一些關鍵點:
-
使用
back_populates
而非backref
,以更清晰地定義雙向關系。 -
通過
uselist
控制關系類型(一對一或一對多)。 -
使用
secondary
指定多對多關系的關聯表。 -
通過
lazy
參數控制加載策略,優化性能。 -
使用
order_by
指定關聯對象的排序方式。