使用 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.xdnf.cn/news/17276.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

PPPoE技术详解

一 , 背景 随着运营商对宽带接入技术要求的不断提高,以xDSL,CableModem和以太网为主的几种宽带接入技术在用户管理和计费等方面的不足开始显露,已无法满足运营商的需求。 在众多的技术中,以太网接入方式经济实惠&…

[JAVA]MyBatis环境配置介绍

什么是MyBatis环境配置? MyBatis是基于JDBC对数据库进行操作,在我们进行数据操作时,我们需要告诉MyBatis我们连接哪个数据库,ip地址,数据库名称,用户名密码等。以此来进行环境配置。 首先,MyB…

Javascirpt时区——脱坑指南

最近业务反馈了一个约课功能的问题,澳大利亚的用户反馈,无法进行选课。排查之后发现是时区不对引起的,由于时区的偏差已经超过时间,导致无法选课。 这里对js中处理时区的问题做一些总结。 时区 时区(Time Zone&#xf…

不用来回切换,一个界面管理多个微信

你是不是也有多个微信号需要管理? 是不是也觉得频繁切换账号很麻烦? 是不是也想提升多账号管理的效率? 在工作中,好的辅助工具,能让我们的效率加倍增长! 今天, 就给大家分享一个多微管理工具…

每日OJ题_牛客_AB32【模板】哈夫曼编码_C++_Java

目录 牛客_AB32【模板】哈夫曼编码 题目解析 C代码 Java代码 牛客_AB32【模板】哈夫曼编码 【模板】哈夫曼编码_牛客题霸_牛客网 描述: 给出一个有n种字符组成的字符串,其中第ii种字符出现的次数为ai​。请你对该字符串应用哈夫曼编码,…

UDP协议

​ UDP协议 前置知识一、应用层的进程为什么要bind端口号二、如何确定网络中的一个进程三、进程 服务 协议 端口之间的关系四、常见的协议对应的端口五、一些命令六、一个进程能不能绑定多个端口号,一个端口号能不能被多个进程绑定七、对任何一个协议报文的认识 UD…

KkFileView4.1.0部署文档--linux

先看下官方文档:kkFileView - 在线文件预览 环境要求中的JDK8如果没有的,需先安装JDK8,这里不做展示。 第二个office相关环境要求在linux中会自动下载安装,不用管。 1、下载地址 Linux 或 MacOS 版: https://kkfil…

[论文笔记]An LLM Compiler for Parallel Function Calling

引言 今天带来一篇优化函数调用的论文笔记——An LLM Compiler for Parallel Function Calling。 为了简单,下文中以翻译的口吻记录,比如替换"作者"为"我们"。 当前的函数(工具)调用方法通常需要对每个函数进行顺序推理和操作&…

基于JAVA的资源检索系统(源码+定制+开发)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

展望:多模态融合与marker推断

技术进步使得利用高维、高通量、多尺度的生物医学数据从多个角度研究患者和疾病成为可能。在肿瘤学中,正在生成大量数据,从分子、组织病理学到临床记录。深度学习的引入极大地促进了生物医学数据的分析。然而,大多数方法都侧重于单一模态&…

AI在电商平台中的创新应用:提升销售效率与用户体验的数字化转型

1. 引言 AI技术在电商平台的应用已不仅仅停留在基础的数据分析和自动化推荐上。随着人工智能的迅速发展,越来越多的电商平台开始将AI技术深度融合到用户体验、定价策略、供应链优化、客户服务等核心业务中,从而显著提升运营效率和用户满意度。在这篇文章…

基于Java Springboot餐厅点餐系统(加入商家版)

一、作品包含 源码数据库设计文档万字全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA 数据库:MySQL5.7…

NeRF在农业领域的应用-------------(1)

一、Exploring Accurate 3D Phenotyping in Greenhouse through Neural Radiance Fields(通过神经辐射场探索温室中精确的三维表型分析) 1.摘要 在精准农业中,准确收集植物表型对于优化可持续农业实践至关重要。 在受控实验室环境中进行的传…

pico-sdk(零)

pico-sdk(零) 项目概述license相关文档 依赖三方库链接 项目概述 Raspberry Pi Pico SDK(以下简称 SDK)提供了为 RP 系列微控制器设备(如 Raspberry Pi Pico 或 Raspberry Pi Pico 2)编写 C、C 或汇编语言…

基于java+SpringBoot+Vue的视频网站系统设计与实现

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot mybatis Maven mysql5.7或8.0等等组成&#x…

vue注册全局组件,其他地方可以直接方便的调用

文章目录 问题注册全局组件完结 问题 本来我们想使用某个组件,需要在各个地方引入对应的参数,并配置好components内容,才可以使用 但是随着用的越来越多,这种方法变得重复且易出错 注册全局组件 修改main.js文件,放…

javaScript交互补充(元素的三大系列)

1、元素的三大系列 1.1、offset系列 1.1.1、offset初相识 使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等 获得元素距离带有定位祖先元素的位置获得元素自身的大小(宽度高度)注意:返回的数值都不…

基于SSM的特色美食推荐平台+LW示例参考

1.项目介绍 系统角色:管理员、普通用户功能模块:管理员(用户管理、店铺管理、美食类型、美食收录管理、论坛交流管理等)、普通用户(登录注册、论坛交流、信息查看、美食收藏、美食资讯等)技术栈&#xff1…

【javascript从零单排】变量let、var、const

🌈"It always seems impossible until it’s done." — Nelson Mandela 种一棵树最好是机会是十年前,其次是现在。 📗概念 在 JavaScript 中,变量是用于存储数据值的容器。可以使用变量来保存不同类型的数据&#xff0…

Marp for VScode插件 PPT无法预览的问题

优质好文:https://blog.csdn.net/lyuhaochina/article/details/141527208 这是因为很多人在VScode中安装markdown插件时都会安装插件Markdown Preview Enhanced,这个插件会和Marp插件的预览功能产生冲突,导致用Marp插件做的PPT无法预览 找到设置选项Markdown-previe…