Sqlalchemy 简明教程
SQLAlchemy ORM - Building Relationship
本会话描述了如何创建另一个表,该表与我们数据库中已存在的表相关。 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.customer 将 Invoice 类链接到 Customer 类。relationship() 使用两个表之间的外键关系来确定此链接的性质,并确定该关系是一对多的关系。
另一个 relationship() 指令会被放置在 Customer 映射类的 Customer.invoices 属性下。relationship.back_populates 参数被分配为引用互补的属性名称,以便每个 relationship() 能够就以相反的方式表达的相同关系做出明智的决策。一方是 Invoices.customer 引用 Invoices 实例,另一方是 Customer.invoices 引用 Customers 实例列表。
该关系函数是 SQLAlchemy ORM 包的 Relationship API 的一部分。它提供两个映射类之间的关系。这对应于父-子或关联表关系。
以下是发现的基本关系模式−
One To Many
一对多的关系是指通过子表上的外键来引用父表的关系。relationship() 然后指定在父表上,作为引用子表中一堆项的集合。relationship.back_populates 参数用于在一对多关系中建立双向关系,其中“反向”侧是多对一关系。