从零接触FastAPI框架,今日学习day04
一、前期回顾
昨天我们了解了什么是ORM,以及使用ORM的优势,以及如何在Fast API中集成数据库
二、今日学习
- 模型设计:如何使用 Tortoise ORM 定义数据表结构
- 数据库迁移:使用 Aerich 工具管理数据库版本
- 接口开发:实现一个基于单表的用户登录接口
安全提示:本文示例为教学演示,密码采用明文存储。在生产环境中,请务必使用passlib或bcrypt对密码进行哈希加密处理!
三、创建模型、模块导出、Aerich 数据库迁移。
创建模型:
1、在我们创建的app软件包的目录下创建一个models的软件包在里面用于创建模型,在app软件包下创建一个user.py的文件,我们可以在这个文件中创建一个user模型,定义一些需要的字段
from tortoise import models, fields class User(models.Model): id = fields.IntField(pk=True) username = fields.CharField(max_length=50,unique=True) password = fields.CharField(max_length=50) email = fields.CharField(max_length=100,unique=True) created_at = fields.DatetimeField(auto_now_add=True) class Meta: table='t_user'我们可以看到User模型继承了tortoise下的modls,然后一定要写id这个为模型中的主键,然后其他字段可以根据使用需求来增加一些约束,比如username这个字段可以增加唯一约束,增加一些字数限制的约束,以下为一些常用的字段类型:
模块导出:
创建好模型后,我们需要导出User模型,在app/models/init.py文件中进行导出
from app.models.user import User __all__ = ['User'] #一边俩下划线Aerich 数据库迁移:
什么是Aerich:Aerich是一个专为Tortoise ORM设计的数据库迁移工具。
核心功能:
- 自动生成迁移文件:对比当前模型定义与数据库实际状态,自动生成增量 SQL 变更脚本。
- 版本化管理:通过迁移文件记录数据库结构的演进历史,支持升级和回滚。
- CLI 驱动:提供命令行工具(如
aerich init-db,aerich migrate,aerich upgrade)来管理整个迁移生命周期。 - 多数据库支持:兼容 PostgreSQL、MySQL、SQLite 等 Tortoise ORM 支持的后端。
首次迁移:
生成迁移文件:aerich init -t app.config.TORTOISE_ORM
(-t后面为数据库配置的TORTOISE_ORM路径,即为app目录下的config文件下的TORTOISE_ORM常量名)后续自己在做练习的时候不在这个目录下记得要更改这个生成迁移文件的命令
初始迁移并应用到数据库(此命令只能第一次执行迁移时使用):aerich init-db
#第二次及以后生成迁移文件:aerich migrate --name 描述名
(--name 描述名可加可不加,加的话就是给你的迁移文件生成一个名字)
#第二次及以后迁移并应用到数据库:aerich upgrade
四、单表增删改查
现在准备工作基本完成,我们可以进行写表的增删改查接口了
创建专门写接口的文件:
我们在前面每创建一个模型就单独创建一个文件,在写接口的文档也是同理,我这里在app目录下创建了个叫api的软件包,里面专门存放写的接口文件,在里面创建一个user.py的文件,写user的接口逻辑
打开app/api/user.py文件下写入
写入
先创建一个路由器:APIRouter
from fastapi import APIRouter user_router = APIRouter( prefix="/users", tags=["用户"], )我们先写一个简单的登录接口,没有返回token和加密的
在app下创建一个叫schemas的软件包,然后在软件包下创建一个user.py文件,定义pydantic对象,接受前端传递的json参数:
# 从 pydantic 库中导入 BaseModel 和 Field 两个核心类 # pydantic 是一个用于数据验证和设置管理的 Python 库 from pydantic import BaseModel, Field # 定义一个用户创建请求的数据模型类 # 继承自 BaseModel,这是 pydantic 中定义数据模型的基础类 class UserLogin(BaseModel): #Field中可以进行一些校验或限制比如...为必传参数,None为可传可不传 username:str=Field( ..., title='用户名', description='用户名', example='admin' ) password:str=Field( ..., title='密码', description='密码', example='123123' )在app/api/user.py下写
#装饰器:post请求的路由 @user_router.post('/login') # async 关键字:声明这是一个异步函数,可以使用 await 调用异步操作 async def get_user(user_request:UserLogin): # await与async同时出现,有async必须要加await user = await User.filter(username=user_request.username, password=user_request.password).first() if not user: return {'code':400,'msg':'用户名或密码错误'} return {'code':200,'msg':'登录成功','data':{'username':user.username,'user_id':user.id}}在main.py中将路由器挂载到主 FastAPI 应用
# 从 user 模块导入路由器实例 from app.api.user import user_router # 将路由器挂载到主 FastAPI 应用 app.include_router(user_router)连接数据库先添加个数据
我这里选择用软件自带的数据库
添加完之后,然后来接口文档测试一下
输入uvicorn main:app --reload启动
点击测试
登录成功
五、总结
一、 核心知识脉络
本次学习完成了从数据库模型设计到接口落地的完整闭环,主要涵盖三大模块:
- 模型层:使用 Tortoise ORM 定义
User模型,掌握主键声明、字段约束(唯一/长度)及元数据表名配置,并通过__all__规范模块导出。 - 迁移层:引入 Aerich 工具管理数据库版本,区分首次初始化(
init-db)与后续迭代(migrate+upgrade)的命令差异,实现模型变更的增量同步。 - 接口层:基于
APIRouter模块化组织路由,结合 Pydantic Schema 完成请求参数校验,实现异步登录查询接口并挂载至主应用。
二、 关键技术要点
- Tortoise ORM 规范:模型必须继承
models.Model且显式定义pk=True的主键字段;所有数据库操作均为异步,必须配合await使用。 - Aerich 命令边界:
aerich init-db仅限项目首次执行,后续任何模型修改严禁重复使用该命令,否则会导致迁移历史混乱。 - Pydantic 校验:使用
Field(...)标记必填参数,通过title/description/examples增强 Swagger 文档可读性(注:V2 版本推荐使用examples替代example)。 - 路由模块化:通过
APIRouter(prefix, tags)定义子路由,再经app.include_router()挂载,避免单文件代码膨胀。
三、 避坑与安全提醒
- 密码安全:当前示例为明文存储密码,仅用于教学演示。生产环境必须使用
passlib/bcrypt进行哈希加密,同时建议将密码字段长度调整为 255 以容纳哈希值。 - 循环导入:模型、Schema、路由文件之间需保持单向依赖,避免交叉引用导致
ImportError。 - 迁移配置路径:
aerich init -t后的配置路径必须与实际项目中TORTOISE_ORM常量的位置完全一致,路径错误会导致迁移失败。
