FastAPI中的依赖注入与数据库事务管理
title: FastAPI中的依赖注入与数据库事务管理
date: 2025/04/09 00:10:29
updated: 2025/04/09 00:10:29
author: cmdragon
excerpt:
FastAPI中使用依赖注入和SQLAlchemy进行数据库会话封装的方法,提供了三种事务管理模式的实现:自动事务模式、手动控制模式和装饰器模式。通过代码示例展示了如何创建用户注册功能,并处理事务和错误。强调了使用参数化查询防止SQL注入攻击的重要性,并提供了常见报错的解决方案,包括检查数据库连接参数、管理会话生命周期和调整连接池设置。
categories:
- 后端开发
- FastAPI
tags:
- 依赖注入
- 数据库会话管理
- 事务管理
- FastAPI
- SQLAlchemy
- 异步编程
- SQL注入防护

扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
- 依赖注入基础与数据库会话封装
(代码示例运行环境:Python 3.8+,需安装fastapi, uvicorn, sqlalchemy, asyncpg)
from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
# 初始化数据库连接(使用异步引擎)
DATABASE_URL = "postgresql+asyncpg://user:password@localhost/dbname"
engine = create_async_engine(DATABASE_URL, echo=True)
async_session_maker = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
# 封装数据库会话依赖
async def get_db() -> AsyncSession:
"""
生成器函数创建数据库会话上下文
使用yield代替return实现资源自动释放
会话自动关闭机制保证连接池回收
"""
async with async_session_maker() as session:
try:
yield session
finally:
await session.close()
app = FastAPI()
@app.post("/users/")
async def create_user(
name: str,
session: AsyncSession = Depends(get_db)
):
"""
路由函数通过Depends自动获取数据库会话
事务管理需要在业务逻辑中显式控制
注意异步await关键字的正确使用
"""
from sqlalchemy import text
try:
# 执行原生SQL示例(实际建议使用ORM)
await session.execute(
text("INSERT INTO users (name) VALUES (:name)"),
{"name": name}
)
await session.commit()
return {"status": "created"}
except Exception as e:
await session.rollback()
raise HTTPException(500, str(e))
- 事务管理的三种实现模式
(1)自动事务模式(适合简单操作):
from fastapi import Depends
from databases import Database
async def transaction_wrapper(db: Database = Depends(get_db)):
async with db.transaction():
yield
(2)手动控制模式(复杂业务场景):
@app.post("/orders/")
async def create_order(
user_id: int,
db: AsyncSession = Depends(get_db)
):
try:
await db.begin()
# 执行多个数据库操作
await db.commit()
except SQLAlchemyError:
await db.rollback()
raise
(3)装饰器模式(代码复用最佳实践):
from contextlib import asynccontextmanager
@asynccontextmanager
async def managed_transaction(db: AsyncSession):
try:
yield
await db.commit()
except Exception:
await db.rollback()
raise
# 在路由中使用
async def create_order(db: AsyncSession = Depends(get_db)):
async with managed_transaction(db):
# 业务逻辑代码
- 完整案例:用户注册连带创建档案
(包含事务管理和错误处理的最佳实践)
from sqlalchemy import insert
from pydantic import BaseModel
class UserCreate(BaseModel):
username: str
email: str
profile: dict
@app.post("/register/")
async def register_user(
user_data: UserCreate,
db: AsyncSession = Depends(get_db)
):
async with db.begin():
try:
# 插入用户主表
user_result = await db.execute(
insert(users_table).values(
username=user_data.username,
email=user_data.email
).returning(users_table.c.id)
)
user_id = user_result.scalar()
# 插入档案子表
await db.execute(
insert(profiles_table).values(
user_id=user_id,
**user_data.profile
)
)
return {"user_id": user_id}
except IntegrityError as e:
await db.rollback()
if "unique constraint" in str(e):
raise HTTPException(400, "Username already exists")
raise HTTPException(500, "Database error")
课后Quiz:
Q1:使用原生SQL查询时,如何防止SQL注入攻击?
A) 直接拼接字符串
B) 使用参数化查询
C) 过滤特殊字符
D) 使用ORM自动处理
正确答案:B
解析:参数化查询通过将用户输入与SQL语句分离的方式,从根本上阻止注入攻击。示例中的text()
函数配合参数字典即为正确做法。即使用ORM,也需要避免直接拼接查询字符串。
常见报错解决方案:
错误现象:
sqlalchemy.exc.InterfaceError: (sqlalchemy.dialects.postgresql.asyncpg.InterfaceError) <class 'asyncpg.exceptions.ConnectionDoesNotExistError'>
原因分析:
- 数据库连接参数配置错误
- 连接池耗尽未正确释放
- 异步上下文管理不当
解决步骤:
- 检查DATABASE_URL格式:postgresql+asyncpg://
- 确保数据库服务正常运行
- 在依赖项中正确使用async with管理会话生命周期
- 调整连接池设置:
engine = create_async_engine(
DATABASE_URL,
pool_size=20,
max_overflow=10,
pool_timeout=30
)
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:FastAPI中的依赖注入与数据库事务管理 | cmdragon's Blog
往期文章归档:
- FastAPI依赖注入作用域与生命周期控制 | cmdragon's Blog
- FastAPI依赖注入实践:工厂模式与实例复用的优化策略 | cmdragon's Blog
- FastAPI依赖注入:链式调用与多级参数传递 | cmdragon's Blog
- FastAPI依赖注入:从基础概念到应用 | cmdragon's Blog
- FastAPI中实现动态条件必填字段的实践 | cmdragon's Blog
- FastAPI中Pydantic异步分布式唯一性校验 | cmdragon's Blog
- 掌握FastAPI与Pydantic的跨字段验证技巧 | cmdragon's Blog
- FastAPI中的Pydantic密码验证机制与实现 | cmdragon's Blog
- 深入掌握FastAPI与OpenAPI规范的高级适配技巧 | cmdragon's Blog
- Pydantic字段元数据指南:从基础到企业级文档增强 | cmdragon's Blog
- Pydantic Schema生成指南:自定义JSON Schema | cmdragon's Blog
- Pydantic递归模型深度校验36计:从无限嵌套到亿级数据的优化法则 | cmdragon's Blog
- Pydantic异步校验器深:构建高并发验证系统 | cmdragon's Blog
- Pydantic根校验器:构建跨字段验证系统 | cmdragon's Blog
- Pydantic配置继承抽象基类模式 | cmdragon's Blog
- Pydantic多态模型:用鉴别器构建类型安全的API接口 | cmdragon's Blog
- FastAPI性能优化指南:参数解析与惰性加载 | cmdragon's Blog
- FastAPI依赖注入:参数共享与逻辑复用 | cmdragon's Blog
- FastAPI安全防护指南:构建坚不可摧的参数处理体系 | cmdragon's Blog
- FastAPI复杂查询终极指南:告别if-else的现代化过滤架构 | cmdragon's Blog
- FastAPI 核心机制:分页参数的实现与最佳实践 | cmdragon's Blog
- FastAPI 错误处理与自定义错误消息完全指南:构建健壮的 API 应用 ️ | cmdragon's Blog
- FastAPI 自定义参数验证器完全指南:从基础到高级实战 | cmdragon's Blog
- FastAPI 参数别名与自动文档生成完全指南:从基础到高级实战 | cmdragon's Blog
- FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战 | cmdragon's Blog
- FastAPI 表单参数与文件上传完全指南:从基础到高级实战 | cmdragon's Blog
- FastAPI 请求体参数与 Pydantic 模型完全指南:从基础到嵌套模型实战 | cmdragon's Blog
- FastAPI 查询参数完全指南:从基础到高级用法 | cmdragon's Blog
- FastAPI 路径参数完全指南:从基础到高级校验实战 | cmdragon's Blog
- FastAPI路由专家课:微服务架构下的路由艺术与工程实践 | cmdragon's Blog
- FastAPI路由与请求处理进阶指南:解锁企业级API开发黑科技 | cmdragon's Blog
- FastAPI路由与请求处理全解:手把手打造用户管理系统 | cmdragon's Blog
- FastAPI极速入门:15分钟搭建你的首个智能API(附自动文档生成) | cmdragon's Blog
- HTTP协议与RESTful API实战手册(终章):构建企业级API的九大秘籍 | cmdragon's Blog
FastAPI中的依赖注入与数据库事务管理的更多相关文章
- Spring学习(三)——Spring中的依赖注入的方式
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...
- ABP中的依赖注入思想
在充分理解整个ABP系统架构之前首先必须充分了解ABP中最重要的依赖注入思想,在后面会具体举出一些实例来帮助你充分了解ABP中的依赖注入思想,在了解这个之前我们首先来看看什么是依赖注入?来看看维基百科 ...
- 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)
相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient ...
- ASP.NET Core 中的依赖注入
目录 什么是依赖注入 ASP .NET Core 中使用依赖注入 注册 使用 释放 替换为其它的 Ioc 容器 参考 什么是依赖注入 软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要 ...
- Android 和 Dagger 2 中的依赖注入
原文:Dependency Injection in Android with Dagger 2 作者:Joe Howard 译者:kmyhy 在现代开发团队中到处充斥着"你一定要用依赖注入 ...
- 深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)【转】
原文链接:https://www.cnblogs.com/gdsblog/p/8465401.html 相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transi ...
- ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下
ADO.NET 一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data → DataTable, ...
- ASP.NET Core 中的 依赖注入介绍
ASP.NET Core 依赖注入 HomeController public class HomeController : Controller { private IStudentReposito ...
- ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入
原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...
- 在WPF中使用依赖注入的方式创建视图
在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...
随机推荐
- JavaWeb的一些理解
WEB概述 WEB是什么 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上的资源分类 Internet上供外界访问的Web资源分为: 静态 ...
- 包装类(Wrapper) 的使用
package com.ch.java2; import org.junit.Test; /* * 包装类的使用: * 1.java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特 ...
- manim边做边学--淡入淡出变换
今天介绍Manim中用于淡入淡出变换的3个动画类: FadeToColor:聚焦于对象颜色的平滑转换,通过渐变增强视觉效果 FadeTransform:实现不同对象之间的渐变替换,让元素转换更加连贯 ...
- Ping测试记录脚本
@echo off echo PingTest del PingTest_result.txt timeout /t 10 echo=> PingTest_result.txt :TEST ec ...
- mysql事务中使用临时表
最近在使用存储过程完成晚上数据的定时汇总功能,其中需要在存储过程中启用事务,但是发现使用了create table语句后事务会自动提交这个语句前的语句,即便是这个语句后发生了错误进行了回滚. 测试语句 ...
- 天翼云存储资源盘活系统HBlock,全面释放企业数据价值
9月6日,天翼云与科技媒体InfoQ联合举办的以"存储难题新解法,揭秘极/致易用的HBlock"为主题的线上技术分享会圆满落幕.天翼云国际业务事业部研发专家武志民与存储产品线总监魏 ...
- StarUML画时序图
一.打开软件,新建时序图 二.画图 2.1 新建用户图标 2.2 新建几个生命线Lifeline 2.3 建立连接关系 2.4 图例
- [大模型/AI/GPT] Chatbox:大模型可视化终端应用
序 概述:Chatbox AI Chatbox AI 是一款 AI 客户端应用和智能助手,支持众多先进的 AI 模型和 API,可在 Windows.MacOS.Android.iOS.Linux 和 ...
- 你的边比较松弛:最短路的 Bellman-Ford 和 SPFA 方法
Dijkstra 的局限性 在带权图的最短路径问题中,我们的目标是从一个起点出发,找到到达其他所有节点的最短路径.无论是交通导航中的最短耗时路线,还是金融网络中的最小成本路径,这一问题的核心始终是如何 ...
- 反范式设计,冗余用户姓名,修改用户姓名后,业务表同步更新 -- MySQL 存储过程
反范式设计,冗余用户姓名,通过存储过程进行业务表的同步更新. 所有的表,在创建的时候,都加了创建人.修改人的字段..用户姓名发生变化时,要将所有的表都更新一遍. 创建存储过程 MySQL CREATE ...