- SQLAlchemy 教程
- SQLAlchemy - 首页
- SQLAlchemy - 简介
- SQLAlchemy Core
- 表达式语言
- 连接数据库
- 创建表
- SQL 表达式
- 执行表达式
- 选择行
- 使用文本SQL
- 使用别名
- 使用 UPDATE 表达式
- 使用 DELETE 表达式
- 使用多个表
- 使用多表更新
- 参数有序更新
- 多表删除
- 使用连接
- 使用连接词
- 使用函数
- 使用集合操作
- SQLAlchemy ORM
- 声明映射
- 创建会话
- 添加对象
- 使用查询
- 更新对象
- 应用过滤器
- 过滤器操作符
- 返回列表和标量
- 文本SQL
- 构建关系
- 处理相关对象
- 处理连接
- 常见关系操作符
- 急切加载
- 删除相关对象
- 多对多关系
- 方言
- SQLAlchemy 有用资源
- SQLAlchemy - 快速指南
- SQLAlchemy - 有用资源
- SQLAlchemy - 讨论
SQLAlchemy ORM - 构建关系
本节描述创建另一个表,该表与我们数据库中已存在的表相关。customers 表包含客户的主数据。我们现在需要创建 invoices 表,该表可能包含属于某个客户的任意数量的发票。这是一种一对多关系的情况。
使用声明式,我们定义此表及其映射类 Invoices,如下所示:
from sqlalchemy import create_engine, ForeignKey, Column, Integer, String engine = create_engine('sqlite:///sales.db', echo = True) from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() from sqlalchemy.orm import relationship class Customer(Base): __tablename__ = 'customers' id = Column(Integer, primary_key = True) name = Column(String) address = Column(String) email = Column(String) class Invoice(Base): __tablename__ = 'invoices' id = Column(Integer, primary_key = True) custid = Column(Integer, ForeignKey('customers.id')) invno = Column(Integer) amount = Column(Integer) customer = relationship("Customer", back_populates = "invoices") Customer.invoices = relationship("Invoice", order_by = Invoice.id, back_populates = "customer") Base.metadata.create_all(engine)
这将向 SQLite 引擎发送一个 CREATE TABLE 查询,如下所示:
CREATE TABLE invoices ( id INTEGER NOT NULL, custid INTEGER, invno INTEGER, amount INTEGER, PRIMARY KEY (id), FOREIGN KEY(custid) REFERENCES customers (id) )
我们可以使用 SQLiteStudio 工具检查 sales.db 中是否创建了新表。
Invoices 类在 custid 属性上应用 ForeignKey 构造。此指令指示此列中的值应约束为 customers 表中 id 列中存在的值。这是关系数据库的核心特性,也是将不相关的表集合转换为具有丰富重叠关系的“粘合剂”。
第二个指令,称为 relationship(),告诉 ORM Invoice 类应使用属性 Invoice.customer 与 Customer 类链接。relationship() 使用两表之间的外键关系来确定此链接的性质,确定它是一对多。
在 Customer 映射类下的 Customer.invoices 属性上放置了额外的 relationship() 指令。relationship.back_populates 参数被分配为引用互补属性名称,以便每个 relationship() 可以对相同关系(以相反的方式表达)做出明智的决定。一方面,Invoices.customer 指的是 Invoices 实例,另一方面,Customer.invoices 指的是 Customers 实例的列表。
relationship 函数是 SQLAlchemy ORM 包的关系 API 的一部分。它提供两个映射类之间的关系。这对应于父子或关联表关系。
以下是找到的基本关系模式:
一对多
一对多关系是指使用子表上的外键来引用父级。然后在父级上指定 relationship(),作为引用由子级表示的项目集合。relationship.back_populates 参数用于在多对一中建立双向关系,其中“反向”侧是多对一。
多对一
另一方面,多对一关系在父表中放置一个外键以引用子级。relationship() 在父级上声明,其中将创建一个新的标量持有属性。这里同样使用 relationship.back_populates 参数来实现双向行为。
一对一
一对一关系本质上是双向关系。uselist 标志指示在关系的“多”侧放置标量属性而不是集合。要将一对多转换为一对一类型的关系,请将 uselist 参数设置为 false。
多对多
多对多关系是通过添加一个关联表来建立的,该关联表通过定义具有其外键的属性来关联两个类。它由 relationship() 的 secondary 参数指示。通常,Table 使用与声明式基类关联的 MetaData 对象,以便 ForeignKey 指令可以找到要链接的远程表。每个 relationship() 的 relationship.back_populates 参数建立双向关系。关系的两侧都包含一个集合。