使用 FastAPI 和 Tortoise ORM 构建高效的异步应用:完整指南

在现代 Web 开发中,选择合适的框架和工具对构建高效的应用至关重要。FastAPI 作为一个快速、现代的 Web 框架,以其异步特性和对 Python 类型提示的支持而备受欢迎。而 Tortoise ORM 则是一个适用于异步应用的轻量级 ORM,特别适合与 FastAPI 结合使用。本文将通过使用 SQLite 数据库,手把手教你如何在 FastAPI 项目中集成 Tortoise ORM,从而实现高效的异步数据库操作。

项目结构

在深入代码实现之前,我们首先规划一下项目的目录结构。这有助于我们更有条理地组织代码。

fastapi_tortoise/
├── app/
│   ├── __init__.py
│   ├── main.py
│   ├── models.py
│   └── routes/
│       ├── __init__.py
│       └── users.py
├── database.py
└── tortoise_config.py

这样的结构将我们的项目分为几个模块:app 用于存放主要的应用逻辑,database.py 用于数据库相关的初始化和连接,tortoise_config.py 则是 Tortoise ORM 的配置文件。

安装和配置

在开始编写代码之前,我们需要先安装必要的库。确保你的 Python 环境中已经安装了 FastAPI 和 Uvicorn:

pip install fastapi uvicorn

接下来,安装 Tortoise ORM 及其 SQLite 驱动:

pip install tortoise-orm aiosqlite

配置 Tortoise ORM

tortoise_config.py 文件中,配置 Tortoise ORM 来连接 SQLite 数据库。

# tortoise_config.py
TORTOISE_ORM = {"connections": {"default": "sqlite://db.sqlite3"},"apps": {"models": {"models": ["app.models", "aerich.models"],"default_connection": "default",},},
}

这里,我们定义了一个默认的数据库连接,使用 SQLite 作为存储后端,数据库文件名为 db.sqlite3

数据库初始化

database.py 文件中,编写初始化和关闭 Tortoise ORM 的代码。

from tortoise import Tortoise, run_asyncasync def init():await Tortoise.init(config=TORTOISE_ORM)await Tortoise.generate_schemas()async def close():await Tortoise.close_connections()

定义模型

接下来,在 app/models.py 中定义我们的数据库模型。以用户模型为例:

from tortoise import fields
from tortoise.models import Modelclass User(Model):id = fields.IntField(pk=True)username = fields.CharField(max_length=50, unique=True)email = fields.CharField(max_length=128, unique=True)password_hash = fields.CharField(max_length=128)class Meta:table = 'users'def __str__(self):return self.username

安全地处理密码

在任何涉及用户密码的应用中,安全性都是至关重要的。我们不能将明文密码直接存储在数据库中,而是应该使用哈希函数进行加密。

我们可以使用 passlib 库来处理密码哈希:

pip install passlib[bcrypt]

app/models.py 中定义一个函数来生成密码哈希:

from passlib.context import CryptContextpwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")def get_password_hash(password: str) -> str:return pwd_context.hash(password)

定义 API 路由

app/routes/users.py 中,定义用户相关的 API 路由,包括创建、读取、更新和删除用户。

from fastapi import APIRouter, HTTPException
from app.models import User
from pydantic import BaseModel, EmailStrrouter = APIRouter()class UserIn(BaseModel):username: stremail: EmailStrpassword: strclass UserOut(BaseModel):id: intusername: stremail: strclass Config:orm_mode = True@router.post("/", response_model=UserOut)
async def create_user(user_in: UserIn):hashed_password = get_password_hash(user_in.password)user = await User.create(username=user_in.username,email=user_in.email,password_hash=hashed_password)return user@router.get("/{user_id}", response_model=UserOut)
async def get_user(user_id: int):user = await User.get_or_none(id=user_id)if not user:raise HTTPException(status_code=404, detail="User not found")return user@router.put("/{user_id}", response_model=UserOut)
async def update_user(user_id: int, user_in: UserIn):user = await User.get_or_none(id=user_id)if not user:raise HTTPException(status_code=404, detail="User not found")user.username = user_in.usernameuser.email = user_in.emailuser.password_hash = get_password_hash(user_in.password)await user.save()return user@router.delete("/{user_id}", status_code=204)
async def delete_user(user_id: int):user = await User.get_or_none(id=user_id)if not user:raise HTTPException(status_code=404, detail="User not found")await user.delete()

数据迁移

Tortoise ORM 集成了 Aerich 以便进行数据库迁移。首先,安装 Aerich:

pip install aerich

然后初始化 Aerich 并生成迁移脚本:

aerich init -t tortoise_config.TORTOISE_ORM
aerich init-db
aerich migrate
aerich upgrade

整合 FastAPI 应用

app/main.py 中,创建 FastAPI 应用并整合 Tortoise ORM 初始化逻辑。

from fastapi import FastAPI
from app.routes import users
import databaseapp = FastAPI()@app.on_event("startup")
async def startup_event():await database.init()@app.on_event("shutdown")
async def shutdown_event():await database.close()app.include_router(users.router, prefix="/users", tags=["users"])

运行应用

使用 Uvicorn 运行 FastAPI 应用:

uvicorn app.main:app --reload

测试 API

使用工具如 Postman 或 curl 测试 API 的各个端点。

创建用户
curl -X POST "http://127.0.0.1:8000/users/" -H "Content-Type: application/json" -d '{"username": "testuser", "email": "test@example.com", "password": "password"}'
获取用户
curl "http://127.0.0.1:8000/users/1"
更新用户
curl -X PUT "http://127.0.0.1:8000/users/1" -H "Content-Type: application/json" -d '{"username": "updateduser", "email": "updated@example.com", "password": "newpassword"}'
删除用户
curl -X DELETE "http://127.0.0.1:8000/users/1"

优化建议

  1. 数据库性能优化

    • 考虑为常用查询添加索引。
    • 使用缓存来减少数据库查询次数。
  2. 安全性增强

    • 实现 JWT 身份验证。
    • 确保所有输入都经过验证和消毒,以防止 SQL 注入和 XSS 攻击。
  3. 测试和持续集成

    • 使用 pytestpytest-asyncio 编写单元测试。
    • 在 CI/CD 流程中自动化测试和部署。

总结

通过本文的指导,你应该能够在 FastAPI 项目中集成 Tortoise ORM,并使用 SQLite 数据库进行异步操作。我们涵盖了从安装配置到实现完整的 CRUD 操作的各个步骤,并提供了一些优化和安全性的建议。希望这篇指南能帮助你在实际项目中更好地应用这些技术。

如果你有任何问题或建议,欢迎在评论区分享你的想法和经验!

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

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

相关文章

学习threejs,使用TWEEN插件实现动画

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.PLYLoader PLY模型加…

前端 JS 实用操作总结

目录 1、重构解构 1、数组解构 2、对象解构 3、...展开 2、箭头函数 1、简写 2、this指向 3、没有arguments 4、普通函数this的指向 3、数组实用方法 1、map和filter 2、find 3、reduce 1、重构解构 1、数组解构 const arr ["唐僧", "孙悟空&quo…

从0开始学习--Day26--聚类算法

无监督学习(Unsupervised learning and introduction) 监督学习问题的样本 无监督学习样本 如图,可以看到两者的区别在于无监督学习的样本是没有标签的,换言之就是无监督学习不会赋予主观上的判断,需要算法自己去探寻区别,第二张…

矩阵数组转置

#include<stdio.h> int main() {int arr1[3][4];//三行四列变成四行三列int arr2[4][3];for(int i0;i<3;i)//三行{for(int j0;j<4;j)//四列{scanf("%d",&arr1[i][j]);//录入}}for(int i0;i<3;i)//转置{for(int j0;j<4;j){arr2[j][i]arr1[i][j]…

利用正则表达式批量修改文件名

首先&#xff0c; 我们需要稍微学习一下正则表达式的使用方式&#xff0c;可以看这里&#xff1a;Notepad正则表达式使用方法_notepad正则匹配-CSDN博客 经过初步学习之后&#xff0c;比较重要的内容我做如下转载&#xff1a; 元字符是正则表达式的基本构成单位&#xff0c;它们…

rust高级特征

文章目录 不安全的rust解引用裸指针裸指针与引用和智能指针的区别裸指针使用解引用运算符 *&#xff0c;这需要一个 unsafe 块调用不安全函数或方法在不安全的代码之上构建一个安全的抽象层 使用 extern 函数调用外部代码rust调用C语言函数rust接口被C语言程序调用 访问或修改可…

【How AI Works】读书笔记3 出发吧! AI纵览 第二部分

目录 1.说明 2.第二部分(P9~P10) 机器学习算法总结(监督学习) 3.单词 4.专业术语 1.说明 书全名:How AI Works From Sorcery to Science 作者 Ronald T.Kneusel 2.第二部分(P9~P10) 总结机器学习算法 作者把机器学习的过程比喻成输入-->黑盒-->输出 这里的标签可…

HarmonyOS NEXT应用开发实战 ( 应用的签名、打包上架,各种证书详解)

前言 没经历过的童鞋&#xff0c;首次对HarmonyOS的应用签名打包上架可能感觉繁琐。需要各种秘钥证书生成和申请&#xff0c;混在一起也分不清。其实搞清楚后也就那会事&#xff0c;各个文件都有它存在的作用。 HarmonyOS通过数字证书与Profile文件等签名信息来保证鸿蒙应用/…

【自用】0-1背包问题与完全背包问题的Java实现

引言 背包问题是计算机科学领域的一个经典优化问题&#xff0c;分为多种类型&#xff0c;其中最常见的是0-1背包问题和完全背包问题。这两种问题的核心在于如何在有限的空间内最大化收益&#xff0c;但它们之间存在一些关键的区别&#xff1a;0-1背包问题允许每个物品只能选择…

Python_爬虫3_Requests库网络爬虫实战(5个实例)

目录 实例1&#xff1a;京东商品页面的爬取 实例2&#xff1a;亚马逊商品页面的爬取 实例3&#xff1a;百度360搜索关键词提交 实例4&#xff1a;网络图片的爬取和存储 实例5&#xff1a;IP地址归地的自动查询 实例1&#xff1a;京东商品页面的爬取 import requests url …

黑马微项目

目录 1 飞机票 2 生成一个五位数验证码 3 数字加密 4 数字解密 5 抢红包 6 双色球系统 7 用户登录 8 金额转换 9 手机号屏蔽 10 罗马数字转换 11 调整字符串 12 初级学生管理系统&#xff08;学生数据的管理&#xff09; 13 学生管理系统&#xff08;用户的相关操…

C2M柔性制造模式

C2M柔性制造模式&#xff08;Customer-to-Manufacturer&#xff0c;客户到制造商的柔性制造模式&#xff09;是一种新型的生产模式&#xff0c;强调客户需求与制造过程的直接对接&#xff0c;并且能够快速响应和适应客户个性化的定制需求。这种模式结合了定制化生产与智能制造&…

IoT [remote electricity meter]

IoT [remote electricity meter] 物联网&#xff0c;远程抄表&#xff0c;电表数据&#xff0c;举个例子

2、开发工具和环境搭建

万丈高楼平地起&#xff0c;学习C语言先从安装个软件工具开始吧。 1、C语言软件工具有两个作用 1、编辑器 -- 写代码的工具 2、编译器 -- 将代码翻译成机器代码0和1 接下来我们介绍两种C语言代码工具&#xff1a;devcpp 和 VS2019&#xff0c;大家可以根据自己的喜好安装。 dev…

20241115在飞凌的OK3588-C的核心板上跑Linux R4时拿大文件到电脑的方法

20241115在飞凌的OK3588-C的核心板上跑Linux R4时拿大文件到电脑的方法 2024/11/15 15:26 缘起&#xff1a;使用SONY 405的机芯&#xff0c;以1080p60录像了半小时&#xff0c;3.5GB的mp4视频要拿到电脑上播放确认。 方法&#xff1a;1、拷贝到TF卡。记住&#xff0c;对于FAT32…

MySQL一些使用操作-持续更新

MySQL相关操作 1.MySQL不删除数据的情况下&#xff0c;让自增id重新排序 应用场景&#xff1a;Mysql&#xff08;当你删除表中数据之后&#xff0c;造成自增id不连续&#xff0c;可能会导致需要用id进行的判断的时候不准确&#xff0c;所以我想到了要重新排序&#xff0c;当然…

async 和 await的使用

一、需求 点击按钮处理重复提交&#xff0c;想要通过disabled的方式实现。 但是点击按钮调用的方法里有ajax、跳转、弹窗等一系列逻辑操作&#xff0c;需要等方法里流程都走完&#xff0c;再把disabled设为false&#xff0c;这样下次点击按钮时就可以继续走方法里的ajax等操作…

解决 idea windows 设置maven离线模式之后,maven继续请求远程仓库

在内网开发的时候经常遇到没有办法来链接远程仓库的情况&#xff0c;这个时候需要设置maven的离线模式。 idea windows 设置maven离线模式之后&#xff0c;maven继续请求远程仓库 当设置完离线模式之后&#xff0c;有的时候执行maven的命令会报错&#xff0c;提示请求远程失败…

StructuredStreaming (一)

一、sparkStreaming的不足 1.基于微批,延迟高不能做到真正的实时 2.DStream基于RDD,不直接支持SQL 3.流批处理的API应用层不统一,(流用的DStream-底层是RDD,批用的DF/DS/RDD) 4.不支持EventTime事件时间&#xff08;一般流处理都会有两个时间&#xff1a;事件发生的事件&am…

Python_爬虫1_Requests库入门

目录 Requests库 7个主要方法 Requests库的get()方法 Response对象的属性 爬取网页的通用代码框架 理解requests库的异常 HTTP协议及Requests库方法 HTTP协议 HTTP协议采用URL作为定位网络资源的标识。 HTTP协议对资源的操作 理解PATCH和PUT的区别 HTTP协议与Requse…