title: FastAPI数据库集成与事务管理

date: 2025/04/18 00:15:34

updated: 2025/04/18 00:15:34

author: cmdragon

excerpt:

FastAPI与SQLAlchemy集成指南:首先配置SQLite数据库连接,创建会话工厂和声明性基类。定义用户模型并映射表结构,使用Pydantic进行数据验证。通过依赖项获取数据库会话,实现用户创建和转账功能。事务控制通过显式开始事务和错误处理确保数据一致性。常见问题包括422验证错误、500服务器错误和完整性错误,需检查请求体、数据库连接和约束。课后Quiz解答事务回滚、SQL注入防护和并发写操作处理。

categories:

  • 后端开发
  • FastAPI

tags:

  • FastAPI
  • SQLAlchemy
  • 数据库集成
  • 事务管理
  • Pydantic
  • 错误处理
  • 并发控制


扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

探索数千个预构建的 AI 应用,开启你的下一个伟大创意

FastAPI数据库集成与事务管理完全指南

1. 环境准备与基础配置

在项目根目录创建database.py文件:

# 安装依赖:pip install fastapi uvicorn sqlalchemy pydantic
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker # 配置SQLite数据库连接(生产环境建议使用PostgreSQL)
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
connect_args={"check_same_thread": False},
echo=True # 显示生成的SQL语句
) # 创建数据库会话工厂
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # 声明性基类
Base = declarative_base()

2. 模型定义与表结构映射

from sqlalchemy import Column, Integer, String

class User(Base):
__tablename__ = "users" id = Column(Integer, primary_key=True, index=True)
name = Column(String(50), nullable=False)
email = Column(String(100), unique=True)
balance = Column(Integer, default=0) # 创建数据库表(生产环境建议使用迁移工具)
Base.metadata.create_all(bind=engine)

3. Pydantic数据模型

from pydantic import BaseModel

class UserCreate(BaseModel):
name: str
email: str
balance: int = 0 class UserResponse(BaseModel):
id: int
name: str
email: str
balance: int class Config:
orm_mode = True # 启用ORM模式转换

4. 路由与数据库操作

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session router = APIRouter() # 依赖项获取数据库会话
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close() @router.post("/users/", response_model=UserResponse)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
# 显式开始事务
transaction = db.begin()
try:
db_user = User(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
except Exception as e:
transaction.rollback()
raise HTTPException(
status_code=400,
detail=f"创建用户失败: {str(e)}"
)

5. 事务控制与错误处理

多操作事务示例:

def transfer_funds(sender_id: int, receiver_id: int, amount: int, db: Session):
transaction = db.begin()
try:
# 获取发送方账户
sender = db.query(User).filter(User.id == sender_id).with_for_update().first()
if not sender or sender.balance < amount:
raise ValueError("余额不足或账户不存在") # 获取接收方账户
receiver = db.query(User).filter(User.id == receiver_id).with_for_update().first()
if not receiver:
raise ValueError("接收方账户不存在") # 执行转账
sender.balance -= amount
receiver.balance += amount db.commit()
return {"message": "转账成功"} except Exception as e:
transaction.rollback()
raise HTTPException(status_code=400, detail=str(e))

6. 常见报错解决方案

问题1:422 Validation Error

  • 现象:请求参数验证失败
  • 解决方法:
    1. 检查请求体是否符合Pydantic模型定义
    2. 使用Swagger UI测试接口
    3. 查看返回的detail字段中的具体错误信息

问题2:500 Internal Server Error

  • 现象:数据库连接失败
  • 解决方法:
    1. 检查数据库URL格式是否正确
    2. 验证数据库服务是否正常运行
    3. 检查数据库用户权限设置

问题3:IntegrityError (sqlalchemy.exc.IntegrityError)

  • 现象:违反数据库约束
  • 解决方法:
    1. 检查唯一性约束字段(如email)
    2. 验证外键关联是否存在
    3. 确保NOT NULL字段都有值

7. 课后Quiz

Q1:以下哪种情况会导致事务自动回滚?

A) 代码中显式调用commit()

B) 发生未捕获的异常

C) 使用with_for_update()

D) 调用refresh()方法

正确答案:B

解析:当数据库操作过程中出现未捕获的异常时,SQLAlchemy会自动回滚当前事务,保证数据一致性。

Q2:如何防止SQL注入攻击?

A) 使用字符串拼接查询

B) 始终使用ORM查询方法

C) 手动转义特殊字符

D) 关闭数据库日志

正确答案:B

解析:SQLAlchemy的ORM系统会自动处理参数化查询,避免直接拼接SQL语句,从根本上防止SQL注入。

Q3:什么情况下需要使用with_for_update()?

A) 需要提高查询性能

B) 处理并发写操作

C) 创建数据库索引

D) 执行批量插入

正确答案:B

解析:with_for_update()在事务中锁定查询行,防止其他事务修改,用于处理需要保证数据一致性的并发写操作场景。

通过本文的学习,您应该已经掌握FastAPI集成SQLAlchemy的核心方法,理解事务控制原理,并能够处理常见的数据库操作问题。建议在实际项目中结合Alembic进行数据库迁移管理,并配置连接池优化性能。

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:FastAPI数据库集成与事务管理 | cmdragon's Blog

往期文章归档:

FastAPI数据库集成与事务管理的更多相关文章

  1. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  2. spring声明式事务管理总结

    事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...

  3. SpringMVC+MyBatis整合——事务管理

    项目一直没有做事务管理,这几天一直在想着解决这事,今天早上终于解决了.接下来直接上配置步骤. 我们项目采用的基本搭建环境:SpringMVC.MyBatis.Oracle11g.WebLogic10. ...

  4. Spring Boot中的事务管理

    原文  http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...

  5. 【Java EE 学习 54】【OA项目第一天】【SSH事务管理不能回滚问题解决】【struts2流程回顾】

    一.SSH整合之后事务问题和总结 1.引入问题:DAO层测试 假设将User对象设置为懒加载模式,在dao层使用load方法. 注意,注释不要放开. 使用如下的代码块进行测试: 会报错:no sess ...

  6. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  7. Spring的事务管理

    事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...

  8. ssh简化后之事务管理

    为了能让大家更好的了解,所以今天跟大家分享整个项目.ps:ssh环境的搭建我就不一一讲解了,请大家参考 http://www.cnblogs.com/zczc1996/p/5842367.html. ...

  9. spring事务管理器设计思想(二)

    上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...

  10. spring事务管理器设计思想(一)

    在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...

随机推荐

  1. ffmpeg简易播放器(4)--使用SDL播放音频

    SDL(英语:Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发函数库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的代码 ...

  2. 【忍者算法】LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中)

    (本文字数2900,阅读大约需15分钟) 上一篇文章我们讨论了如何科学地刷题,今天我要带大家深入了解这100道精选题目背后的分类逻辑.作为一名面试官,我希望通过这篇文章,为大家绘制一张完整的算法知识地 ...

  3. TIPTOP应付账款流程学习

    应付账款流程与应收账款流程是财务管理的开端,也是财务工作的主要流程. 企业的应付账款有很多种,如原材料的应付账款.电力能源的应付账款.房租的应付账款等,大头是原材料的应付账款,以下详细说明. 在讲解之 ...

  4. IPTools for .NET:快速查询全球IP信息

    IPTools 是一个用于快速查询全球 IP 地址信息的库,支持国内和国际 IP 查询,提供详细的地理位置信息(如国家.省份.城市)以及经纬度等数据. 1. IPTools.China IPTools ...

  5. EasyExcel合并行处理并优化

    业务场景 由于业务需要导出如下图中订单数据和订单项信息,而一个订单对应多个订单项,所以会涉及到自定义合并行 1.简单处理项目使用的EasyExcel,经查找发现Excel种有个AbstractMerg ...

  6. Bean的原始版本与最终版本不一致?记一次Spring IOC探索之旅

    前言 在这个信息技术发展迅速的时代,万万没想到,Spring自2003年发展至今,仍是技术选型中的首选,某些项目甚至有Spring全家桶的情况. 在Java开发者面试当中,Spring的原理也常被面试 ...

  7. MediaToolkit:.NET 开发者的多媒体处理工具

    MediaToolkit:.NET 开发者的多媒体处理工具 在开发过程中处理音频和视频文件是许多应用程序的重要功能.MediaToolkit 是一个强大的 .NET 库,帮助开轻松处理这些多媒体文件. ...

  8. SIT、UAT以及PROD环境的区别

    题记部分 一.SIT环境   SIT(System Integration Testing)环境主要用于系统集成测试,旨在验证系统中不通模块之间的集成和交互是否正常工作.这个环境通常用于开发团队内部进 ...

  9. Linux - 开启FTP服务

    vsftpd 一.Centos6.x配置ftp 1.1.安装OpenSSH-server OpenSSH-server包含了FTP服务,通常,CentOS6.x默认已经安装了OpenSSH-serve ...

  10. HTTPS 与 HTTP 的区别在哪?

    HTTP与HTTPS作为互联网数据传输的核心协议,其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验.本文将解析两者的通信流程.安全机制及核心差异. 一.HTTP的通信机制 先来看看HTTP ...