title: FastAPI与SQLAlchemy数据库集成与CRUD操作

date: 2025/04/16 09:50:57

updated: 2025/04/16 09:50:57

author: cmdragon

excerpt:

FastAPI与SQLAlchemy集成基础包括环境准备、数据库连接配置和模型定义。CRUD操作通过数据访问层封装和路由层实现,确保线程安全和事务管理。常见错误如422请求验证错误通过Pydantic模型和中间件处理。Session生命周期管理依赖注入系统保证每个请求独立会话。常见报错如数据库连接失败和事务回滚通过检查服务状态、验证连接参数和异常处理解决。

categories:

  • 后端开发
  • FastAPI

tags:

  • FastAPI
  • SQLAlchemy
  • 数据库集成
  • CRUD操作
  • Session管理
  • 错误处理
  • MySQL


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

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

1. FastAPI 与 SQLAlchemy 同步数据库集成基础

1.1 环境准备与安装

首先创建虚拟环境并安装必要依赖:

python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate.bat # Windows
pip install fastapi uvicorn sqlalchemy pymysql

1.2 数据库连接配置

database.py中配置核心数据库连接:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker SQLALCHEMY_DATABASE_URL = "mysql+pymysql://user:password@localhost/mydatabase"
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
pool_size=20,
max_overflow=0,
pool_pre_ping=True
) SessionLocal = sessionmaker(
autocommit=False,
autoflush=False,
bind=engine,
expire_on_commit=False
)

1.3 模型定义与关系映射

models.py中定义数据模型:

from sqlalchemy import Column, Integer, String
from database import Base 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)
age = Column(Integer, default=18) def __repr__(self):
return f"<User(name='{self.name}', email='{self.email}')>"

2. CRUD 操作标准实现模式

2.1 数据访问层封装

创建repository.py实现CRUD操作:

from sqlalchemy.orm import Session
from models import User class UserRepository:
@staticmethod
def create_user(db: Session, user_data: dict):
""" 创建用户 """
db_user = User(**user_data)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user @staticmethod
def get_user(db: Session, user_id: int):
""" 根据ID获取用户 """
return db.query(User).filter(User.id == user_id).first() @staticmethod
def update_user(db: Session, user_id: int, update_data: dict):
""" 更新用户信息 """
db_user = db.query(User).filter(User.id == user_id).first()
if db_user:
for key, value in update_data.items():
setattr(db_user, key, value)
db.commit()
db.refresh(db_user)
return db_user @staticmethod
def delete_user(db: Session, user_id: int):
""" 删除用户 """
db_user = db.query(User).filter(User.id == user_id).first()
if db_user:
db.delete(db_user)
db.commit()
return True
return False

2.2 路由层实现

main.py中定义API端点:

from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from models import Base
from database import engine, SessionLocal
from repository import UserRepository
from pydantic import BaseModel Base.metadata.create_all(bind=engine) app = FastAPI() # 依赖注入获取数据库会话
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close() class UserCreate(BaseModel):
name: str
email: str
age: int = 18 @app.post("/users/")
def create_user(user: UserCreate, db: Session = Depends(get_db)):
return UserRepository.create_user(db, user.dict()) @app.get("/users/{user_id}")
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = UserRepository.get_user(db, user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user

3. Session 生命周期管理

3.1 Session 线程安全策略

通过依赖注入系统保证每个请求独立会话:

def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

3.2 事务管理最佳实践

def transfer_funds(db: Session, from_id: int, to_id: int, amount: float):
try:
from_user = UserRepository.get_user(db, from_id)
to_user = UserRepository.get_user(db, to_id) if from_user.balance < amount:
raise ValueError("Insufficient funds") from_user.balance -= amount
to_user.balance += amount db.commit()
except Exception as e:
db.rollback()
raise e

4. 常见错误处理

4.1 422 请求验证错误

示例场景

{
"detail": [
{
"loc": [
"body",
"age"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}

解决方案

  1. 检查请求体是否匹配Pydantic模型定义
  2. 使用OpenAPI文档进行测试
  3. 添加中间件捕获验证错误:
from fastapi.exceptions import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return JSONResponse(
status_code=400,
content={"detail": exc.errors(), "body": exc.body},
)

课后Quiz

问题1:以下哪种方式可以有效防止SQL注入攻击?

A) 使用字符串拼接SQL语句

B) 使用ORM的查询参数化功能

C) 在数据库连接字符串添加特殊参数

D) 禁用所有输入验证

答案:B) 正确。SQLAlchemy等ORM框架会自动进行参数化查询,将用户输入作为参数传递而不是直接拼接到SQL语句中。

问题2:为什么需要在finally块中关闭数据库会话?

A) 为了提升查询性能

B) 确保会话在任何情况下都会被正确关闭

C) 防止其他请求使用该会话

D) 满足数据库连接池的要求

答案:B) 正确。无论是否发生异常,finally块中的代码都会执行,保证会话资源的正确释放。

常见报错解决方案

**报错1

**:sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost'")

原因分析

  • 数据库服务未启动
  • 连接参数(用户名/密码/端口)错误
  • 网络防火墙阻止连接

解决方案

  1. 检查MySQL服务状态
  2. 验证连接字符串参数
  3. 使用telnet测试端口连通性
  4. 添加连接超时参数:
create_engine(connect_args={"connect_timeout": 10})

**报错2

**:sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush.

原因分析

  • 数据库操作违反约束(如唯一性约束)
  • 事务未正确处理异常

解决方案

  1. 检查数据完整性约束
  2. 在事务代码块中添加try/except
  3. 执行显式回滚操作
  4. 使用session.expire_all()重置会话状态

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

往期文章归档:

FastAPI与SQLAlchemy数据库集成与CRUD操作的更多相关文章

  1. 【翻译】MongoDB指南/CRUD操作(四)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(四) 1 查询方案(Query Plans) MongoDB 查询优化程序处理查询并且针对给定可利用的索引选 ...

  2. 【翻译】MongoDB指南/CRUD操作(三)

    [原文地址]https://docs.mongodb.com/manual/ CRUD操作(三) 主要内容: 原子性和事务(Atomicity and Transactions),读隔离.一致性和新近 ...

  3. 【翻译】MongoDB指南/CRUD操作(二)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,SQL与MongoDB映射图,读隔离(读关 ...

  4. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  5. ASP.NET Core Web API Cassandra CRUD 操作

    在本文中,我们将创建一个简单的 Web API 来实现对一个 “todo” 列表的 CRUD 操作,使用 Apache Cassandra 来存储数据,在这里不会创建 UI ,Web API 的测试将 ...

  6. MongoDB的CRUD操作

    1. 前言 在上一篇文章中,我们介绍了MongoDB.现在,我们来看下如何在MongoDB中进行常规的CRUD操作.毕竟,作为一个存储系统,它的基本功能就是对数据进行增删改查操作. MongoDB中的 ...

  7. 【Java EE 学习 44】【Hibernate学习第一天】【Hibernate对单表的CRUD操作】

    一.Hibernate简介 1.hibernate是对jdbc的二次开发 2.jdbc没有缓存机制,但是hibernate有. 3.hibernate的有点和缺点 (1)优点:有缓存,而且是二级缓存: ...

  8. 使用MyBatis对表执行CRUD操作

    一.使用MyBatis对表执行CRUD操作——基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0&quo ...

  9. MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013540.html 上一篇博文MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybati ...

  10. MyBatis入门学习教程-使用MyBatis对表执行CRUD操作

    上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...

随机推荐

  1. 基本类型、包装类与String类间的转换

  2. 深度学习基础理论————CV中常用Backbone(Resnet/Unet/Vit系列/多模态系列等)以及代码

    主要介绍在CV中常用的Backbone原理简易代码(代码以及原理经常更新),参考论文中的表格,对不同的任务所使用的backbone如下: 针对上面内容分为两块内容:1.基于卷积神经网络的CV Back ...

  3. Windows 本地虚拟磁盘

    本文介绍如何本地创建虚拟磁盘 虚拟磁盘vhdx是类似物理硬盘一样的磁盘,可以被格式化.内部添加分区,可以指定系统文件格式如NTFS.exFAT 一个vhdx文件对应一个虚拟磁盘,下面我们来操作vhdx ...

  4. AllPairs工具助力正交表测试用例设计

    AllPairs工具助力正交表测试用例设计 正交表法是一种高效的测试方法,特别适用于软件测试中需要处理多个控件及其多种取值组合的情况.以下是对正交表法的详细解释: 一.正交表法概述 正交表法是一种利用 ...

  5. [源码分析] Facebook如何训练超大模型--- (5)

    [源码分析] Facebook如何训练超大模型--- (5) 目录 [源码分析] Facebook如何训练超大模型--- (5) 0x00 摘要 0x01 背景 0x02 思路 2.1 学习建议 2. ...

  6. Kyuubi支持Iceberg配置

    一.简述 Kyuubi调用Spark来查询iceberg表,修改Spark配置信息即可. 二.服务配置 1.上传jar包到Kyuubi server节点 可以选择emr spark组件后,按照配置组( ...

  7. Amis坑

    一.特殊字符 1.输入框.多行输入框输入$s字符默认替换成空. 如调用后端接口的输入框输入123$BB123,实际请求的参数为123,$后面的参数消息 解决办法:如确实需要输入$的话,在$前面加\即可 ...

  8. 理解ID3决策树

    决策树是一个树形结构,类似下面这样: 上图除了根节点外,有三个叶子节点和一个非叶子节点. 在解决分类问题的决策树中,叶子节点就表示所有的分类,比如这里的分类就有3种:无聊时阅读的邮件.需及时处理的邮件 ...

  9. ABB喷涂机器人维护保养

    正确规范的ABB喷涂机器人保养能够最大限度保证机器人正常运行, 保证经济效率并提高产量.因此,预防性喷涂机器人保养是一项不可或缺的工作. ABB喷涂机器人正常运行每3年或10000小时后,则需要做一次 ...

  10. 推荐一款最新开源,基于AI人工智能UI自动化测试工具!支持自然语言编写脚本!

    随着互联网技术的飞速发展,Web应用越来越普及,前端页面也越来越复杂.为了确保产品质量,UI自动化测试成为了开发过程中不可或缺的一环.然而,传统的UI自动化测试工具往往存在学习成本高.维护困难等问题. ...