共计 1435 个字符,预计需要花费 4 分钟才能阅读完成。
在使用 SQLModel 操作数据库时,除了基本的增删改查,实际应用中常常需要跨表联合查询和分页功能。今天我们通过一些具体案例,来学习如何在 SQLModel 中使用这些功能。
一、联合查询(Join)
假设我们有两个表:User 和 Post,并且它们通过 user_id 字段关联,一个用户可以拥有多篇文章。
我们想要查询所有文章及其对应作者的名字:
from sqlmodel import select, Session
from sqlalchemy.orm import joinedload
def get_posts_with_users():
with Session(engine) as session:
statement = select(Post).options(joinedload(Post.user))
results = session.exec(statement).all()
for post in results:
print(f" 文章标题:{post.title},作者:{post.user.name}")
说明:
- 使用
joinedload可以在一次查询中预加载关联的用户信息,避免 N+1 查询问题。
二、条件联合查询
比如,我们只想查询标题中包含“Python”的文章及其作者:
def search_posts_with_keyword(keyword: str):
with Session(engine) as session:
statement = select(Post).where(Post.title.contains(keyword)).options(joinedload(Post.user))
results = session.exec(statement).all()
for post in results:
print(f"{post.title} - 作者:{post.user.name}")
三、分页查询
分页是大多数 Web 应用的基本需求,下面是一个简单的分页实现:
def get_posts_paginated(page: int = 1, page_size: int = 5):
offset = (page - 1) * page_size
with Session(engine) as session:
statement = select(Post).offset(offset).limit(page_size).options(joinedload(Post.user))
results = session.exec(statement).all()
for post in results:
print(f"[{post.id}] {post.title} - {post.user.name}")
四、统计总记录数
为了配合分页功能,通常我们还需要查询总记录数:
from sqlalchemy import func
def get_total_posts_count():
with Session(engine) as session:
total = session.exec(select(func.count()).select_from(Post)).one()
print(f" 总文章数:{total}")
五、小结
通过 joinedload 和分页参数 offset + limit,我们可以优雅地实现联合查询和分页功能。理解这些技术将大大提升你构建数据库驱动型应用的能力。
下一节我们将探索 SQLModel 的进阶特性:模型继承与通用查询封装,让我们的代码更易维护、更可复用。
正文完