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. linux:项目上线

    服务器选择 项目上线服务器必须是外网服务器 真实服务器 成本过高.多用于测试 云服务器 阿里云.腾讯云.百度云.华为云.盛大云.新浪云.亚马逊云等 官网:阿里云 1.注册/登录后 2.支付成功即可![ ...

  2. 153:从shell提示符编辑文本文件

  3. CentOS 7 MongoDB 重装启动失败

    诊断过程 1. 错误提示: > journalctl -xe 提示: .... ERROR: child process failed, exited with error number 14 ...

  4. dart中类详细讲解

    dart是一门面向对象的语言 dart是一门实用类和单继承的面向对象的语言 在dart中所有的对象都是类的实例. 所有的类都是Object的子类 类都是有属性和方法组成的 定义一个类 在dart中,我 ...

  5. Linux中如何将txt文件转为png格式

    Linux中如何将txt文件转为png格式 linux将txt文件转为png格式如果文本中没有中文,使用enscript,如果文本包含中文,使用paps命令.但是实际使用中,paps部分版本也不支持中 ...

  6. [图形绘制/流程图] Mermaid : 开源的低代码图形绘制语言、协议及工具

    概述:Mermaid Mermaid‌是一种基于Javascript的.开源的文本驱动图表生成工具/绘图工具,,使用类似于Markdown的低代码语法,它允许用户使用简单的文本语言来创建各种类型的图表 ...

  7. Java 将 RTF 转换为Word、PDF、HTML、图片

    RTF文档因其跨平台兼容性而广泛使用,但有时在不同的应用场景可能需要特定的文档格式.例如,Word文档适合编辑和协作,PDF文档适合打印和分发,HTML文档适合在线展示,图片格式则适合社交媒体分享.因 ...

  8. Linux驱动---设备驱动模型

    目录 一.简介 二.驱动模型 2.1.总线 2.2.设备 2.3.驱动 三.设备树 3.1.设备树简介 3.2.设备树格式 3.3.节点格式 3.4.节点属性 四.设备树API函数 4.1获取设备节点 ...

  9. 2023LN省选游记

    前言 CSP第一轮都考完了,我才写这个游记.我真懒惰 书接上回 正文 Day -114514 我也没想到我居然能报省选. 报上了.准备去爆零. Day -114513~Day -1 学习暴力算法以及痛 ...

  10. CommonLang3-使用介绍

    学习要带着目的,参照现实问题 本次目标: 了解 CommonsLang3 API 文档,找对路后以后开发直接查询 API 文档,摈弃盲目的百度 掌握基础的字符串.日期.数值等工具方法,初步替代手搓的工 ...