共计 1600 个字符,预计需要花费 4 分钟才能阅读完成。
在数据库设计中,表与表之间往往存在联系,比如一个用户可以拥有多个订单,一个班级可以有多个学生。这种情况就属于“一对多”关系。在 SQLModel 中,可以通过外键和关系映射实现一对多的建模。
一、一对多关系的基本概念
一对多关系的特点是:A 表中的一条记录可以关联 B 表中的多条记录,而 B 表中的每条记录只能关联 A 表中的一条记录。例如:
- 用户表和订单表:一个用户可以有多个订单,但每个订单只能属于一个用户。
- 分类表和商品表:一个分类下可以有多个商品,但每个商品只属于一个分类。
二、SQLModel 中的一对多建模
在 SQLModel 中,可以使用 Field 定义外键,用 Relationship 来定义关系。
示例:用户和订单的一对多关系
from typing import List, Optional
from sqlmodel import Field, Relationship, SQLModel
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
# 定义一对多关系,orders 是一个列表
orders: List["Order"] = Relationship(back_populates="user")
class Order(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
item: str
user_id: int = Field(foreign_key="user.id")
# 反向关系
user: Optional[User] = Relationship(back_populates="orders")
这里:
Order表的user_id字段是外键,关联User表的主键id。- 在
User类中,orders使用Relationship定义,表示一个用户可以拥有多个订单。 - 在
Order类中,user表示订单属于哪个用户。
三、插入和查询数据
from sqlmodel import Session, create_engine, select
engine = create_engine("sqlite:///database.db")
# 插入数据
with Session(engine) as session:
user = User(name="Alice")
order1 = Order(item="Book", user=user)
order2 = Order(item="Pen", user=user)
session.add(user)
session.commit()
# 查询数据
with Session(engine) as session:
statement = select(User).where(User.name == "Alice")
result = session.exec(statement).first()
print(" 用户:", result.name)
for order in result.orders:
print(" 订单:", order.item)
输出结果:
用户:Alice
订单:Book
订单:Pen
四、一对多关系的应用场景
- 电商系统:用户与订单、商品与分类。
- 学校系统:班级与学生、老师与课程。
- 企业系统:部门与员工、项目与任务。
通过一对多关系建模,可以让业务逻辑更加清晰,数据查询和维护也更加方便。
五、小结
SQLModel 提供了简洁的方式来定义一对多关系。通过 Field(foreign_key=...) 定义外键,再使用 Relationship 进行映射,就能轻松实现业务系统中的一对多场景。在使用时,应当明确关系的方向,并在类中添加 back_populates 保证数据同步。
下一节我们将继续学习 SQLModel 中的多对多关系映射,探索更复杂的数据建模方法。
正文完