SQLModel教程:在FastAPI中使用多个模型处理数据

SQLModel教程:在FastAPI中使用多个模型处理数据

理解模型分层设计

在构建Web API时,一个常见需求是对同一数据实体使用不同的模型表示形式。SQLModel结合FastAPI提供了优雅的解决方案,让我们能够清晰地分离不同场景下的数据模型。

为什么需要多个模型?

  1. 数据库模型:直接映射到数据库表结构
  2. 创建模型:定义创建资源时所需的字段
  3. 公共模型:定义返回给客户端的字段

这种分层设计带来了诸多好处:

  • 安全性:避免暴露敏感字段
  • 灵活性:不同场景使用不同字段集合
  • 可维护性:各模型职责单一明确

代码解析

数据库模型定义

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)

Hero类继承自SQLModel并设置table=True,表示这是一个数据库模型。关键点:

  • id字段作为主键,使用Optional表示创建时可空
  • nameage字段添加了索引以提高查询性能
  • secret_name是必填字段但不建立索引

创建模型定义

class HeroCreate(SQLModel):
    name: str
    secret_name: str
    age: Optional[int] = None

HeroCreate模型用于创建英雄时的输入验证:

  • 不包含id字段,因为由数据库自动生成
  • 所有字段与数据库模型对应,但去除了数据库特定配置

公共模型定义

class HeroPublic(SQLModel):
    id: int
    name: str
    secret_name: str
    age: Optional[int] = None

HeroPublic模型定义了API返回给客户端的数据结构:

  • 包含id字段,因为创建后需要返回给客户端
  • 字段与数据库模型一致,但可根据需要隐藏或转换某些字段

FastAPI集成实践

数据库初始化

sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True, connect_args={"check_same_thread": False})

def create_db_and_tables():
    SQLModel.metadata.create_all(engine)

这段代码配置了SQLite数据库并创建表结构:

  • echo=True会在控制台输出执行的SQL语句,方便调试
  • check_same_thread=False是SQLite在多线程环境下的必要配置

API端点实现

创建英雄端点

@app.post("/heroes/", response_model=HeroPublic)
def create_hero(hero: HeroCreate):
    with Session(engine) as session:
        db_hero = Hero.model_validate(hero)
        session.add(db_hero)
        session.commit()
        session.refresh(db_hero)
        return db_hero

关键点:

  • 使用HeroCreate模型作为输入参数类型
  • response_model=HeroPublic指定返回数据类型
  • model_validate方法将创建模型转换为数据库模型
  • 使用上下文管理器自动处理会话生命周期

获取英雄列表端点

@app.get("/heroes/", response_model=List[HeroPublic])
def read_heroes():
    with Session(engine) as session:
        heroes = session.exec(select(Hero)).all()
        return heroes

特点:

  • 直接返回数据库查询结果,FastAPI会自动转换为HeroPublic模型
  • 使用SQLModel的select构建查询语句
  • response_model指定返回的是列表形式

最佳实践建议

  1. 模型命名规范:保持一致的命名约定,如XxxCreateXxxPublic
  2. 字段一致性:确保不同模型间相同含义的字段使用相同类型
  3. 最小暴露原则:公共模型只暴露必要字段
  4. 文档注释:为每个模型和字段添加文档字符串,便于生成API文档
  5. 模型验证:利用Pydantic的验证功能在模型层面保证数据质量

通过这种分层模型设计,我们的API能够更好地应对需求变化,同时保持代码的清晰和可维护性。SQLModel与FastAPI的结合为Python开发者提供了强大而简洁的工具,让数据模型的定义和使用变得更加高效。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

FastAPISQLModel 是 Python 中非常流行的用于构建 Web API 的工具和技术栈组合。 SQLModel 是基于 SQLAlchemy 核心库和 Pydantic 库的一个轻量级 ORM 工具,它简化了数据库操作并提高了代码的简洁性和易读性。结合 FastAPI 使用可以快速地创建高效、可靠的 RESTful API 接口,并轻松处理多表之间的关联查询等复杂业务场景。 对于 **fastapi + sqlmodel** 环境下实现多表的操作主要包括以下几个方面: ### 1. 创建模型 首先你需要定义好每个表格对应的 `SQLModel` 模型类,通过设置外键来表示不同数据表之间的一对一、一对多以及多对多的关系。 例如有一个用户表(User)和订单表(Order),其中 User 可能会有多个 Order,则可以在定义这两个模型的时候声明它们间存在的关系: ```python from typing import List, Optional from sqlmodel import Field, Relationship, Session, SQLModel, create_engine class User(SQLModel, table=True): id: int = Field(default=None, primary_key=True) name: str orders: List["Order"] = Relationship(back_populates="user") class Order(SQLModel, table=True): id: int = Field(default=None, primary_key=True) user_id: int = Field(foreign_key="user.id") total_amount: float # 关联到用户的反向引用 user: "User" = Relationship(back_populates="orders") # 如果需要初始化SQLite内存数据库供测试使用的话 engine = create_engine("sqlite:///test.db") def create_db_and_tables(): SQLModel.metadata.create_all(engine) create_db_and_tables() ``` 上述示例展示了如何建立两张有直接联系的数据表;此外我们还指定了双向导航属性以便于从任意一侧访问对方记录集合。 ### 2. 进行CRUD操作 当完成了实体建模之后就可以编写视图函数来进行增删改查等功能实现了,在此过程中往往涉及到了跨表查询或者更新的问题 - 而这正是借助ORM框架最大的便利之处之一! 比如插入新纪录时自动填充相关字段值(如order中的user_id),亦或是加载某个顾客及其所有购买过的商品列表等等... 以下是关于获取某位客户的所有订单信息的例子: ```python @app.get("/users/{id}/orders/", response_model=List[OrderRead]) async def read_user_orders(id: int) -> List[Order]: with Session(engine) as session: statement = select(Order).where(Order.user_id == id) results = session.exec(statement) return list(results) ``` 在这个例子中,`select()` 函数用来构造 SELECT 查询语句,而 `.exec()` 则负责执行该命令并将结果集映射成相应的 Python 对象返回给前端展示。 --- 最后值得注意的是尽管这里只介绍了最基本的一些概念,实际项目里可能会遇到更复杂的嵌套层级结构及性能优化需求等问题 —— 因此掌握更多高级特性的应用也非常重要哦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

费津钊Bobbie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值