SQLModel 教程:使用外键关联查询英雄与团队数据
概述
本文将深入讲解如何使用 SQLModel 进行表关联查询操作,重点演示如何通过外键关系查询英雄(Hero)及其所属团队(Team)的数据。SQLModel 是一个强大的 Python ORM 工具,它结合了 SQLAlchemy 和 Pydantic 的优点,为开发者提供了简洁高效的数据模型定义和数据库操作方式。
数据模型定义
首先我们定义了两个数据模型类:
class Team(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True)
headquarters: str
class Hero(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True)
secret_name: str
age: Optional[int] = Field(default=None, index=True)
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
关键点说明:
Team
模型代表英雄团队,包含团队ID、名称和总部地址Hero
模型代表英雄,包含英雄ID、名称、秘密身份、年龄和所属团队IDteam_id
字段通过foreign_key="team.id"
建立了与Team
表的外键关系- 两个模型都继承自
SQLModel
并设置table=True
表示它们是数据库表模型
数据库连接与初始化
我们使用 SQLite 数据库进行演示:
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True)
echo=True
参数会在控制台输出执行的SQL语句,便于调试。
数据创建流程
1. 创建数据库表
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
这个方法会创建所有定义的数据模型对应的数据库表。
2. 创建初始数据
def create_heroes():
with Session(engine) as session:
# 创建两个团队
team_preventers = Team(name="Preventers", headquarters="Sharp Tower")
team_z_force = Team(name="Z-Force", headquarters="Sister Margaret's Bar")
# 创建三个英雄,其中两个有团队归属
hero_deadpond = Hero(name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id)
hero_rusty_man = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48, team_id=team_preventers.id)
hero_spider_boy = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
# 提交到数据库
session.add_all([team_preventers, team_z_force, hero_deadpond, hero_rusty_man, hero_spider_boy])
session.commit()
# 刷新对象以获取数据库生成的ID等属性
for hero in [hero_deadpond, hero_rusty_man, hero_spider_boy]:
session.refresh(hero)
print("Created hero:", hero)
关联查询实现
核心的关联查询功能在 select_heroes
函数中实现:
def select_heroes():
with Session(engine) as session:
statement = select(Hero, Team).join(Team, isouter=True)
results = session.exec(statement)
for hero, team in results:
print("Hero:", hero, "Team:", team)
关键点解析:
select(Hero, Team)
表示我们要同时查询 Hero 和 Team 表的数据.join(Team, isouter=True)
表示使用外连接(LEFT OUTER JOIN)关联 Team 表isouter=True
确保即使英雄没有团队也会被查询出来
session.exec(statement)
执行查询语句- 遍历结果时,每个结果项包含英雄对象和对应的团队对象
执行流程
def main():
create_db_and_tables() # 创建数据库和表
create_heroes() # 插入测试数据
select_heroes() # 执行关联查询
if __name__ == "__main__":
main()
实际应用场景
这种关联查询在实际开发中非常常见,例如:
- 显示用户及其所属部门信息
- 展示订单及其关联的商品详情
- 查询文章及其作者信息
SQLModel 的这种查询方式相比原生SQL更加直观和安全,避免了SQL注入风险,同时保持了代码的可读性。
总结
通过本教程,我们学习了:
- 如何使用 SQLModel 定义具有外键关联的数据模型
- 如何创建数据库表和初始化数据
- 如何使用
select
和join
进行关联查询 - 外连接(
isouter=True
)的使用场景
SQLModel 的这种关联查询方式既保留了SQLAlchemy的强大功能,又通过类型提示和简洁的API提高了开发效率和代码质量。对于需要处理复杂数据关系的应用,这种模式特别有价值。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考