构建现代 Python Web 应用的最佳实践:从 FastAPI 到 Tortoise ORM20241113

构建现代 Python Web 应用的最佳实践:从 FastAPI 到 Tortoise ORM


随着现代 Web 开发技术的快速演进,Python 的生态系统涌现出了诸多优秀的框架和工具,FastAPITortoise ORM 就是其中的佼佼者。这篇博客将围绕如何使用这两款工具构建高效、可维护的 Web 应用展开讨论,同时分享在实际项目中我们遇到的挑战、解决方案及优化技巧。


引言

在现代 Web 应用的开发中,开发者普遍追求以下目标:

  • 高性能:应用能够快速响应用户请求。
  • 高可维护性:代码清晰易读,便于团队协作和后期维护。
  • 开发效率:能够快速开发 MVP(最小可行产品)并适应不断变化的需求。

FastAPI 凭借其简洁、强大的类型系统和异步支持,成为了构建高性能 Web 应用的热门选择。而 Tortoise ORM 则提供了一种与 Django ORM 类似的体验,专注于异步操作和模型管理。两者的结合让开发者能够专注于业务逻辑,而无需在框架的复杂性上纠结。


核心内容

1. FastAPI 与 Tortoise ORM 的协作机制

在构建 API 时,数据模型是开发的核心。FastAPI 与 Tortoise ORM 的结合通过以下机制提升了开发体验:

数据模型定义与序列化

在 FastAPI 中,我们通过 Tortoise ORM 来定义数据模型,并使用 Pydantic 提供的 pydantic_model_creator 将模型转换为 Pydantic 的数据验证模型:

from tortoise.contrib.pydantic import pydantic_model_creator
from models import Goods# 定义序列化模型
Goods_Pydantic = pydantic_model_creator(Goods, name="Goods")
GoodsIn_Pydantic = pydantic_model_creator(Goods, name="GoodsIn", exclude_readonly=True)

好处:

  • 简化序列化与反序列化逻辑:通过 pydantic_model_creator,无需手动编写序列化代码。
  • 保持一致性:ORM 模型与 API 数据模型共享同一数据结构。

区别与联系:

  • Goods_Pydantic:是用于输出数据的 Pydantic 模型。它通过 pydantic_model_creator 自动生成,反映了数据库中 Goods 模型的字段和类型,支持查询时的序列化。通过它,我们可以将数据库查询结果转换为 JSON 格式,以供 API 响应使用。

  • GoodsIn_Pydantic:是用于输入数据验证的 Pydantic 模型。通过 exclude_readonly=True,我们排除了数据库模型中只读的字段,使得在创建新商品时,这些字段不会被客户端意外修改。


异步数据库操作

FastAPI 和 Tortoise ORM 都支持 Python 的异步特性,允许更高效的 I/O 操作。以下示例展示了如何异步获取数据库中的所有商品:

@router.get("/")
async def get_goods():goods = await Goods_Pydantic.from_queryset(Goods.all())return goods

亮点:

  • from_queryset 能高效地从 ORM 查询集中生成 Pydantic 数据模型,减少手动数据转换的开销。
  • 全程异步,避免了阻塞主线程的可能性。

2. 健康检查与全局异常处理

健康检查

为 Web 应用添加健康检查接口,可以让开发者和运维团队实时监控系统状态:

@app.get("/health", tags=["health"])
async def health_check():try:await Tortoise.init(db_url=db_url, modules={"models": ["models"]})await Tortoise.close_connections()return {"status": "ok", "database": "connected"}except Exception as exc:raise HTTPException(status_code=500, detail=f"Health check failed: {str(exc)}")

使用场景:

  • 自动化监控:运维工具可以定期调用 /health 接口检查服务状态。
  • 快速故障诊断:当接口返回非 200 状态码时,可以直接查看问题描述。

代码解析:

  • 我们通过 Tortoise.init() 来测试数据库的连接。
  • 如果数据库连接成功,返回 { “status”: “ok”, “database”: “connected” },否则抛出异常,告知服务不可用。

全局异常处理

为了提高应用的稳定性和用户体验,我们可以捕获未处理的异常并返回统一的错误响应:

# 全局异常处理器
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):logger.error(f"Unhandled exception: {exc}", exc_info=True)if isinstance(exc, DBConnectionError):return JSONResponse(status_code=500,content={"detail": "Internal Server Error","error": "Database connection failed" if not IS_DEV else str(exc),},)return JSONResponse(status_code=500,content={"detail": "Internal Server Error","error": "An unexpected error occurred" if not IS_DEV else str(exc),},)

优势:

  • 提升用户体验:捕获所有未被处理的异常,避免异常泄漏到客户端,在生产环境下隐藏错误的具体细节,只返回通用的错误提示,比如 “Internal Server Error”,避免暴露敏感信息。
  • 统一异常处理逻辑:开发环境下可以显示完整的错误栈,便于快速定位问题,在一个地方集中管理错误响应逻辑,代码更易维护。

3. 路由分组与文档优化

路由分组

使用 tags 字段为路由分类可以提高文档的可读性。例如:

@router.get("/", tags=["goods"])
async def list_goods():return {"message": "Listing all goods"}

在 Swagger UI 中,所有带有 tags=["goods"] 的路由将会分组在一起,方便开发者快速浏览。

URL 设计

结合 tags 字段,URL 路径的设计也至关重要。推荐使用 RESTful 风格的路径:

  • 列表查询GET /goods
  • 详情查询GET /goods/{id}
  • 创建资源POST /goods
  • 更新资源PUT /goods/{id}
  • 删除资源DELETE /goods/{id}

4. 实践中的挑战与优化

数据库连接管理

在实际项目中,数据库连接可能会遇到超时或配置错误的问题。通过以下方式,可以提升连接管理的稳定性:

  • 在全局初始化时确保数据库连接的正确性。
  • 使用 Tortoise.close_connections() 确保连接的释放,避免资源泄漏。
代码复用

对于 CRUD 操作,可以提取通用逻辑,减少重复代码。例如,统一处理数据库查询的异常:

async def fetch_object_or_404(model, **filters):obj = await model.filter(**filters).first()if not obj:raise HTTPException(status_code=404, detail="Object not found")return obj

结论

通过合理使用 FastAPITortoise ORM,开发者可以快速构建出高效、可维护的 Web 应用。以下是一些关键总结:

  1. FastAPI 提升开发效率:其直观的路由设计和 Pydantic 支持让开发者能更专注于业务逻辑。
  2. Tortoise ORM 提供异步支持:结合 Pydantic,简化了数据模型的定义与序列化。
  3. 健康检查与全局异常处理:增强了系统的稳定性和可维护性。

推荐实践

  • 标签分组与文档优化:为路由添加 tagssummary,提升接口文档的可读性。
  • 统一异常处理:捕获并格式化错误信息,提升用户体验。
  • 清晰的路径设计:结合 RESTful 风格和路由分组,让接口设计更易理解。

通过这些技巧,您可以高效构建并维护高质量的 Python Web 应用,让项目从开发到运维都更加顺畅。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0开始学习机器学习--Day24--核函数

核函数(Kernelsl function) 非线性数据的决策边界 对于非线性问题来说,决策边界在很多时候都是曲线,需要我们在假设函数中加入高阶多项式来拟合原始数据,这对于算法来说需要很长的运行时间去计算这些高阶多项式,那么有没有更高效…

charles简单使用

一、安装&配置 1、安装 通过官网下载稳定版的charles。 说明:官网下载也可以免费使用,不用到处找破解版,还不安全。官网下载的也能用半小时,然后重启一下还能继续用。如果有钱就买个服务,如果不原因花钱就动一动…

VMware和CentOS 7.6 Linux操作系统的安装使用

1. 安装VMware 安装VMware之前,有些电脑是需要去BIOS里修改设置开启cpu虚拟化设备支持才能安装。如果运气不好在安装过程中安装不了的话就自行百度吧。 打开 VMware 的官网: https://www.vmware.com/ 点击 product,往下滑找到 see desktop hypeerviso…

OCP证书如何下载?

访问Oracle CertView网站: 打开网址 https://certview.oracle.com/ ,这是Oracle官方提供的证书查询平台 。 登录账号: 使用您的Oracle账号和密码登录CertView。如果您不记得密码,可以通过注册账号时预留的邮箱重置密码 。 查看成…

将vscode的终端改为cygwin terminal

现在终端是默认的power shell,没有显示cygwin 接下来选择默认配置文件 找到cygwin的选项即可 然后提示可能不安全什么的,点是,就有了

html+js+css实现拖拽式便签留言

前些日子在网上冲浪时,看到一个便签式留言墙,让人耳目一新。心想这个看着不错,额想要。于是便开始搜寻是否有相应开源插件,想将其引入自己的博客中。但是搜寻了一圈,都没有符合预期的,要么功能不符合。有的功能符合&am…

C++入门基础知识147—【关于C++ 一元运算符重载】

成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于C 一元运算符重载的相关内容&#xff0…

2022年蓝桥杯JavaB组 省赛 题目解析(含AC_Code)

目录 前言(必读)第一题:星期计算 (简单)问题描述思路AC代码总结 第二题 山 (简单)问题描述题目分析山形数定义解题思路代码实现解析代码详解回文和“山形”判断函数主函数 AC代码复杂度分析 总结…

NLP论文速读(微软出品)|使用GPT-4进行指令微调(Instruction Tuning with GPT-4)

论文速读|Instruction Tuning with GPT-4 论文信息: 简介: 这篇论文试图解决的问题是如何通过指令调优(instruction-tuning)提升大型语言模型(LLMs)在执行新任务时的零样本(zero-shot&#xff0…

C++20 概念与约束(3)—— 约束的进阶用法

《C20 概念与约束(1)—— SFINAE》 《C20 概念与约束(2)—— 初识概念与约束》 ●《C20 概念与约束(3)—— 约束的进阶用法》 1、再谈约束主句与从句 上一篇文章中提到过约束可以无限嵌套。末尾也提到不…

c#使用COM接口设置excel单元格宽高匹配图片,如何计算?

c#使用COM接口设置excel单元格宽高如何换算 在实际工作中,经常需要在excel中插入图片。并设置单元格与图片对齐。但是excel单元格的宽度和高度使用不同的单位。单元格的宽度以字符宽度为单位,而高度以点为单位。如果按照实际值来设置,例如设…

【activiti工作流源码集成】springboot+activiti+mysql+vue+redis工作流审批流集成整合业务绑定表单流程图会签驳回

工作流集成实际项目案例,demo提供 源码获取方式:本文末个人名片直接获取。 前言 activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,请假审批demo从流程绘制到审批结束实例。 一、项目形式 springbootvue…

CKA认证 | Day2 K8s内部监控与日志

第三章 Kubernetes监控与日志 1、查看集群资源状态 在 Kubernetes 集群中,查看集群资源状态和组件状态是非常重要的操作。以下是一些常用的命令和解释,帮助你更好地管理和监控 Kubernetes 集群。 1.1 查看master组件状态 Kubernetes 的 Master 组件包…

推荐一款好用的postman替代工具2024

Apifox 是国内团队自主研发的 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台,是非常好的一款 postman 替代工具。 它通过一套系统、一份数据,解决多个系统之间的数据同步问题。只要定义好接口文档,接口调试、数据 Mock、接口…

gdb调试redis。sudo

1.先启动redis-server和一个redis-cli。 2.ps -aux|grep reids查看redis相关进程。 3.开始以管理员模式附加进程调试sudo gdb -p 2968.注意这里不能不加sudo,因为Redis 可能以 root 用户启动,普通用户无法附加到该进程。否则就会出现可能下列情形&#…

YUM 的使用

YUM 是一个用于 Fedora 和 Red Hat 以及 CentOS 操作系统的前端软件包管理器,它可以自动处理依赖关系并一次性安装所有必需的软件包。 镜像站点选择 1. 备份原有的镜像源配置文件 系统默认的 yum 镜像源配置文件存储在 /etc/yum.repos.d/ 目录下,可以…

力扣 LeetCode 242. 有效的字母异位词(Day3:哈希表)

解题思路: 哈希表三种数据结构的选择 1. 数组:适用于数据量小的情况 2. set:适用于数据量大的情况 3. map:适用于key-value 什么时候用哈希表? 给你一个元素,判断该元素在这个集合里是否出现过 本题使…

【MYSQL】锁详解(全局锁、表级锁、行级锁)【快速理解】

目录 一、全局锁 二、表级锁 1.表锁 2.元数据锁 3.意向锁 三、行级锁 1. 行锁 2.间隙锁 3.临建锁 锁是处理并发情况下,对数据的一致性的关键因素,也是并发情况下对效率影响非常大的。 1、全局锁:锁定表中所有数据。 2、表级锁:…

蓝桥杯每日真题 - 第11天

题目:(合并数列) 题目描述(14届 C&C B组D题) 解题思路: 题意理解:给定两个数组,目标是通过若干次合并操作使两个数组相同。每次合并操作可以将数组中相邻的两个数相加&#xff…

contos7.9 部署3节点 hadoop3.4 集群 非高可用

contos7.9 部署3节点 hadoop3.4 集群 非高可用 contos7.9 部署3节点 hadoop3.4 集群 非高可用环境信息服务器角色分配服务器配置服务器配置初始化 init_server.sh配置主机名映射所有节点配置 hosts文件 配置免密登录 hadoop 安装环境配置下载安装包下载 jdk1.8hadoop3.4 分发安…