FastAPI 入门的后续以及Tortoise-ORM集成
一、查询参数Query Parameters查询参数是URL中?后面的键值对组合格式为key1value1key2value2用于对资源进行「筛选、分页、排序」等辅助操作。例如/items?skip0limit10skip跳过条数、limit查询条数是查询参数/users?name张三age20name姓名、age年龄是查询参数核心特点可选性默认可省略可设置默认值辅助性不用于标识唯一资源仅用于过滤、分页等灵活性支持单个键对应多个值如/items?tagsfruittagscheap为什么需要Query类型注解基础的查询参数写法如skip: int 0只能实现「类型校验默认值」但实际开发中需要更精细的控制分页参数limit必须≥1且≤50范围校验搜索关键词q长度必须≤100长度限制筛选标签tags支持多个值传入多值参数接口文档需要显示查询参数的详细描述元数据配置Query类型注解正是为解决这些问题而生它是FastAPI提供的「查询参数高级配置工具」与Path注解同源均基于Pydantic功能互补。查询参数 vs 路径参数核心区别什么是Query类型注解Query是FastAPI从fastapi模块导出的专用类用于对查询参数进行「精细化配置」功能与Path注解一致仅适用场景不同。核心特点兼容Python原生类型注解支持更丰富的校验规则配置自动同步到/docs接口文档提升可读性基于Pydantic实现校验失败返回标准化422错误支持多值参数、正则匹配等高级特性Query注解最简示例python# Query类型注解基础示例 fromfastapiimportFastAPI,Queryimportuvicorn appFastAPI(titleQuery注解教程,version1.0.0)# Query注解限制limit≥1且≤50添加详细描述app.get(/items/advanced/,summaryQuery注解基础示例)defread_items_advanced(# 核心语法参数名: 类型 Query(默认值, 校验规则/元数据)skip:intQuery(0,ge0,description跳过条数不能为负数),limit:intQuery(10,ge1,le50,description查询条数1-50条)): Query注解分页接口 :param skip: 跳过条数≥0 :param limit: 查询条数1-50 :return: 分页结果 fake_items[{item_id:i,name:f物品{i}}foriinrange(skip,skiplimit)]return{code:200,skip:skip,limit:limit,data:fake_items}if__name____main__:uvicorn.run(main:app,host127.0.0.1,port8000,reloadTrue)### 核心校验规则参数 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/4675a7b1a3f24f43ae342a020bbfca9a.png#pic_center) # 二、请求体与 Pydantic 模型 请求体解决的问题 1.- 路径参数只能传递简单值ID、名称且长度有限 2.- 查询参数适合传递少量辅助数据传递复杂数据如用户注册信息、商品详情时 URL 会冗长、不安全 优势 数据容量大、格式灵活支持 JSON / 表单 / 文件、传输安全配合 HTTPS #### 三个核心参数类型的适用场景对比 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/71dd17f6c9934ae88feaa15bb861da37.png#pic_center) ## 请求体通常与「非查询类」HTTP 方法配合使用符合 RESTful 规范 POST创建资源如用户注册、新增商品→ 必用请求体 - PUT全量更新资源如修改商品所有信息→ 必用请求体 - PATCH部分更新资源如修改商品价格→ 常用请求体 - GET查询资源 → 禁止使用请求体不符合 HTTP 规范 ## 带字段校验的请求体模型 python python # Pydantic字段校验示例 from fastapi import FastAPI from pydantic import BaseModel, Field import uvicorn app FastAPI(title请求体字段校验教程, version1.0.0) # 带字段校验的用户注册模型 class UserCreateWithValidate(BaseModel): 带字段校验的用户注册请求体模型 # 用户名3-20位仅字母/数字/下划线必填 username: str Field( ..., # 必填字段 min_length3, max_length20, patternr^[a-zA-Z0-9_]$, title用户名, description3-20位仅支持字母、数字、下划线, examplezhangsan_123 ) # 邮箱符合邮箱格式必填 email: str Field( ..., patternr^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$, title邮箱, description请输入合法的邮箱地址, examplezstest.com ) # 密码6-20位必填 password: str Field( ..., min_length6, max_length20, title密码, description6-20位字符建议包含字母和数字, example123456a ) # 年龄1-120岁可选默认None age: int | None Field( None, ge1, le120, title年龄, description1-120岁之间, example25 ) # 带校验的注册接口 app.post(/users/register/validate/, summary带字段校验的注册接口) def user_register_validate(user_info: UserCreateWithValidate): return { code: 200, message: 注册成功带字段校验, data: { username: user_info.username, email: user_info.email, age: user_info.age or 未填写 } } if __name__ __main__: uvicorn.run(main:app, host127.0.0.1, port8000, reloadTrue)# 三、什么是 ORM为什么要用 Tortoise-ORM ORM 全称是 Object-Relational Mapping对象关系映射 。它的核心思想是用 Python 类来代表数据库中的表用类的实例来代表表中的一行记录。 没有 ORM 时你需要手写 SQL 语句来操作数据库。 ## ORM 的优势 - 面向对象用 Python 代码替代 SQL 语句更符合编程思维。 - 安全性自动进行参数化查询防止 SQL 注入攻击。 - 跨数据库同一套代码可以无缝切换 SQLite、PostgreSQL、MySQL 等数据库。 - 关系管理自动处理表与表之间的外键、多对多等关系。 - 可维护性表结构集中定义在模型类中修改和管理更方便。 ### 为什么选择 Tortoise-ORM 在 Python 异步 Web 开发中传统的 ORM如 SQLAlchemy 1.x 的同步模式在执行数据库查询时会阻塞整个线程这与 FastAPI 的异步非阻塞理念背道而驰通常使用Tortoise-ORM或者SQLAlchemy 2.0。 ### 同步 ORM vs 异步 ORM 对比 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/bfd81b2d5a564283972dc20636a50acf.png#pic_center) ## 环境搭建与 FastAPI 集成 python pip install tortoise-orm #MySQL 异步驱动推荐 asyncmy pip install asyncmy 或者 pip install aiomysql # 安装 Aerich 迁移工具后面会用到 pip install aerich # 安装 FastAPI 和 Uvicorn pip install fastapi uvicorn[standard]项目结构规划数据库配置文件配置中最重要的就是这一部分。关系字段的 on_delete 策略详解在定义 ForeignKeyField 或 OneToOneField 时必须指定 on_delete 参数它定义了当父表记录被删除时子表关联记录的行为。这是保证数据一致性的重要一环单表查询先定义User模型 app/models/user.py再导出user模型app/models/init.py然后Aerich 数据库迁移最后查询数据app/routers/user.py示例fromdatetimeimportdatetime,date,timedeltafromfastapiimportAPIRouter,Queryfromtortoise.expressionsimportQfromapp.modelsimportTaskfromapp.schemas.day01importTaskCreateRequest task_routerAPIRouter(prefix/task,tags[任务管理],)task_router.get(/all,summary获取所有任务,description获取所有任务)asyncdefgetAllTask(status:int|NoneQuery(None,description0待办 1进行中 2已完成 3已取消不传查全部),keyword:strQuery(,description任务标题模糊搜索关键词),sort_priority:boolQuery(False,descriptionTrue按优先级紧急→高→中→低排序False默认创建时间倒序)):queryQ()ifstatusisnotNone:queryQ(statusstatus)ifkeyword.strip():queryQ(title__icontainskeyword.strip())task_queryTask.filter(query)# 3. 优先级排序紧急(3)→高(2)→中(1)→低(0)降序ifsort_priority:task_querytask_query.order_by(-priority)else:# 默认按创建时间倒序task_querytask_query.order_by(-created_at)tasksawaittask_query.all()# 通过任务状态查询tasks_list[]fortaskintasks:tasks_list.append({id:task.id,title:task.title,status:task.status,priority:task.priority,due_date:task.due_date,created_at:task.created_at,})return{code:1,message:success,data:tasks_list}注意一定要在在man.py中注册子路由注释上面示例写了查全部以及条件查询和排序并在其中查询时做判断没传就为空或者为设置的默认值传了直接查询。单表增加和查询过程一样导包和名称不再展示示例task_router.post(/save,summary保存任务,description保存任务)asyncdefsave_task(task:TaskCreateRequest):task1awaitTask.create(user_idtask.user_id,titletask.title,descriptiontask.description,statustask.status,prioritytask.priority,due_datetask.due_date)return{code:1,message:保存成功,data:task1}其中所要添加的字段我已在schemas中验证会在最后展示它全部的代码单表修改示例task_router.put(/update/{id},summary修改数据,description修改数据)asyncdefupdate_task(id:int,task:TaskCreateRequest):task1awaitTask.get_or_none(idid)iftask1isNone:return{code:0,message:任务不存在}task_dicttask.dict(exclude_unsetTrue)awaitTask.filter(idid).update(**task_dict)return{code:1,message:修改成功}单表删除示例;task_router.delete(/delete/{id},summary删除任务,description删除任务)asyncdefdelete_task(id:int):task1awaitTask.get_or_none(idid)iftask1isNone:return{code:0,message:任务不存在}awaitTask.filter(idid).delete()return{code:1,message:删除成功}schemas的代码frompydanticimportBaseModel,FieldclassTaskCreateRequest(BaseModel):user_id:intField(...,title用户ID,description用户ID,example1)title:strField(...,title任务标题,min_length1,max_length100,description任务标题,example学习FastAPI)description:strField(None,title任务描述,min_length1,max_length1000,description任务描述,example学习FastAPI)status:intField(0,title任务状态,description任务状态,example0)priority:intField(1,title任务优先级,description任务优先级,example1)#截止时间不能早于当前时间due_date:strField(None,title任务截止时间,description任务截止时间,example2026-07-20 00:00:00)classTaskUpdateRequest(BaseModel):title:strField(None,title任务标题,min_length1,max_length100,description任务标题,example学习FastAPI)description:strField(None,title任务描述,min_length1,max_length1000,description任务描述,example学习FastAPI)status:intField(None,title任务状态,description任务状态,example0)priority:intField(None,title任务优先级,description任务优先级,example1)due_date:strField(None,title任务截止时间,description任务截止时间,example2026-07-20 00:00:00)completed_at:strField(None,title任务完成时间,description任务完成时间,example2026-07-20 00:00:00)今天主要掌握这些

相关新闻

Zephyr SDK 1.0.1 安装与配置指南:基于STM32F103C8T6的完整开发环境搭建

Zephyr SDK 1.0.1 安装与配置指南:基于STM32F103C8T6的完整开发环境搭建

如果你手上有一块 STM32F103C8T6 最小系统板,想用 Zephyr RTOS 来开发,那么第一步,也是最关键的一步,就是搞定 Zephyr SDK。很多人卡在这一步,不是因为 SDK 本身多复杂,而是因为环境、路径、版本和后续的编…

2026/9/25 3:33:48 阅读更多 →
终极跨平台UI迁移方案:7天将WPF应用升级为Avalonia全平台应用

终极跨平台UI迁移方案:7天将WPF应用升级为Avalonia全平台应用

终极跨平台UI迁移方案:7天将WPF应用升级为Avalonia全平台应用 【免费下载链接】Avalonia Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The future of .NET UI 项目地址: https://gitcode.com/GitHub_Trending/ava/Avalonia 想…

2026/9/25 2:47:56 阅读更多 →
Funchook高级技巧:prehook功能详解和参数获取方法终极指南

Funchook高级技巧:prehook功能详解和参数获取方法终极指南

Funchook高级技巧:prehook功能详解和参数获取方法终极指南 【免费下载链接】funchook Hook function calls by inserting jump instructions at runtime 项目地址: https://gitcode.com/gh_mirrors/fu/funchook Funchook是一个功能强大的API钩子库&#xff0…

2026/9/25 6:53:53 阅读更多 →

最新新闻

OpenCode 与 OpenCLAW 的 AI 模型配置:用 TaoToken 统一 Key 打通多工具调用

OpenCode 与 OpenCLAW 的 AI 模型配置:用 TaoToken 统一 Key 打通多工具调用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:13:40 阅读更多 →
ORACLE 经验两则:Sys_Refcursor 与外部表 SKIP 的配置骨架

ORACLE 经验两则:Sys_Refcursor 与外部表 SKIP 的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:13:40 阅读更多 →
Claude 在得物 App 数仓的深度集成与效能演进:TaoToken 统一 Key 通道配置实战

Claude 在得物 App 数仓的深度集成与效能演进:TaoToken 统一 Key 通道配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:13:40 阅读更多 →
WorkBuddy Enterprise 企业级 Agent 平台架构与 MCP 落地实践

WorkBuddy Enterprise 企业级 Agent 平台架构与 MCP 落地实践

1. 从「超级个体」到「超级团队」:这个平台到底在解决什么问题第一次看到「WorkBuddy Enterprise」这个名字,我脑子里蹦出来的第一个念头是:腾讯云终于把 CodeBuddy 那套东西往企业级方向推了。如果你最近半年一直在关注 Agent 开发这条线&am…

2026/9/25 13:13:40 阅读更多 →
Atlas 300V 24G实战:AI推理加速卡部署YOLO全流程

Atlas 300V 24G实战:AI推理加速卡部署YOLO全流程

很多人都为一个词搜过来:atlas。准确讲,搜到atlas又能和部署yolo扯上关系的,多半是盯上了华为Atlas 300V 24G这块卡。今天我不绕圈子,先说结论:Atlas 300V 24G确实是一块运算加速卡,但它更准确的定位&#…

2026/9/25 13:13:40 阅读更多 →
MySQL表空间传输:从原理到实战,把大表迁移从小时级压缩到分钟级

MySQL表空间传输:从原理到实战,把大表迁移从小时级压缩到分钟级

老规矩,先给结论:MySQL自带的表空间传输(Transportable Tablespace)功能,是处理“单表或一批表快速换实例”最好用的手段之一,尤其在数据量已经上到几十GB、几百GB,mysqldump导出导入慢到让人抓…

2026/9/25 13:12:40 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →