详解SQLAlchemy的函数relationship

server/2025/2/12 4:32:56/

在 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")

在上述代码中,ParentchildrenChildparent 通过 back_populates 建立了双向关系。

3. backref

backref 是一个较老的参数,用于在目标模型中自动创建一个反向引用字段。它是一个字符串,表示在目标模型中创建的字段名称。
例如:

class Parent(Base):__tablename__ = 'parents'id = Column(Integer, primary_key=True)children = relationship("Child", backref="parent")

Child 模型中会自动创建一个名为 parent 的字段,指向 Parent 模型。

注意backrefback_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. primaryjoinsecondaryjoin

这两个参数用于显式指定连接条件,通常在复杂的外键关系中使用。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 指定关联对象的排序方式。


http://www.ppmy.cn/server/166952.html

相关文章

Unity-Mirror网络框架-从入门到精通之LagCompensation示例

文章目录 前言什么是滞后补偿Lag Compensation示例延迟补偿原理ServerCubeClientCubeCapture2DSnapshot3D补充LagCompensation.cs 独立算法滞后补偿器组件注意:算法最小示例前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。本系列文章将为读者提供对Mir…

什么是网络安全审计?网络安全审计的作用...

网络安全审计通过对网络数据的采集、分析、识别,实时动态监测通信内容、网络行为和网络流量,发现和捕获各种敏感信息、违规行为,实时报警响应,全面记录网络系统中的各种会话和事件,实现对网络信息的智能关联分析、评估…

spring cloud和spring boot的区别

Spring Cloud和Spring Boot在Java开发领域中都是非常重要的框架,但它们在目标、用途和实现方式上存在明显的区别。以下是对两者区别的详细解析: 1. 含义与定位 Spring Boot: 是一个快速开发框架,它简化了Spring应用的初始搭建以…

华为昇腾报:aclrtMemMallocPolicy:ACL_MEM_MALLOC_HUGE_FIRST

aclrtMemMallocPolicy 是华为昇腾(Ascend)AI处理器中用于设置内存分配策略的一个函数。ACL_MEM_MALLOC_HUGE_FIRST 是其中的一种内存分配策略选项。 1. aclrtMemMallocPolicy 函数 功能: 该函数用于设置内存分配策略,以控制内存分配时的行为…

已验证正常,Java输入字符串生成PDF文件

Java输入字符串生成PDF文件过程&#xff1a; 在Java开发中&#xff0c;如何将字符串转换为 PDF 是一个常见的需求。网上找了很多例子都无法生成&#xff0c;经过多次尝试&#xff0c;终于实现了&#xff0c;特此记录一下。 1、引入pom.xml 添加所需的依赖 <dependency>&…

QTC++

#include "widget.h" #include "ui_widget.h" #include<QFontDialog>//字体对话框 #include<QFont>//字体类 #include<QMessageBox> #include<QColorDialog> #include<QColor> #include<QString> #include<QFileDi…

scss模块化

sccc运行时模块化&#xff1a;同css导入&#xff0c;在项目运行时才会导入解析 inport url(./common.scss)scss编译时模块化&#xff1a;能够获取和使用导入scss的函数和变量&#xff0c;存在以下问题 与sccc运行时模块化容易混淆 在导入多个scss时&#xff0c;会存在变量污染…

小白零基础学习深度学习之张量

1.张量 PyTorch 中的张量&#xff08;Tensor&#xff09;就是一种用来存储数据的“盒子”&#xff0c;这个盒子可以有不同的形状和大小&#xff0c;里面可以装各种数字。张量是 PyTorch 中最基本的东西&#xff0c;就像乐高积木一样&#xff0c;你可以用它来搭建各种复杂的模型…