title: FastAPI与SQLAlchemy同步数据库集成

date: 2025/04/15 01:27:37

updated: 2025/04/15 01:27:37

author: cmdragon

excerpt:

FastAPI与SQLAlchemy集成通过ORM框架实现Python类与数据库表的双向转换。SQLAlchemy提供Core层和ORM层,FastAPI选择ORM层以符合Pythonic风格。声明式模型通过declarative_base()创建基类,定义数据库结构。数据库引擎通过连接字符串配置,会话管理机制确保操作生命周期。完整示例展示了用户管理API的实现,包括创建和查询接口。常见问题涉及会话报错和数据验证错误,解决方案包括检查表结构和验证请求格式。高级配置技巧包括复合索引优化和事务管理。

categories:

  • 后端开发
  • FastAPI

tags:

  • FastAPI
  • SQLAlchemy
  • ORM框架
  • 数据库集成
  • 声明式模型
  • 会话管理
  • Pydantic


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

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

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

1.1 ORM框架核心原理

ORM(Object-Relational Mapping)相当于数据库世界的翻译官,将Python类对象与数据库表进行双向转换。就像邮局工作人员把信件分拣到不同国家的邮筒,ORM自动将类属性映射为表字段,将对象操作转换为SQL语句。

SQLAlchemy作为Python最强大的ORM工具,提供两种模式:

  • Core层:SQL表达式语言,直接操作SQL抽象层
  • ORM层:声明式模型,面向对象方式操作数据库

FastAPI选择ORM层实现数据库集成,因其符合Pythonic编程风格,且能与Pydantic完美配合。

1.2 声明式模型定义

声明式模型就像建筑蓝图,通过类定义描述数据库结构。我们使用declarative_base()创建基类,所有模型继承这个基类获得映射能力。

# 安装必要库(运行环境要求Python3.7+)
# pip install fastapi sqlalchemy pydantic uvicorn from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime # 创建基类(相当于所有模型的DNA)
Base = declarative_base() class User(Base):
__tablename__ = 'users' # 数据库表名 id = Column(Integer, primary_key=True, index=True)
username = Column(String(50), unique=True, nullable=False)
email = Column(String(100), index=True)
created_at = Column(DateTime, default=datetime.utcnow) def __repr__(self):
return f"<User {self.username}>"

字段类型映射关系:

Python类型 SQL类型 说明
Integer INTEGER 32位整数
String(50) VARCHAR(50) 变长字符串,需指定长度
DateTime DATETIME 日期时间类型
Boolean BOOLEAN 布尔值
Float FLOAT 浮点数

1.3 数据库连接配置

数据库引擎是ORM与数据库的通信枢纽,连接字符串格式:dialect+driver://user:password@host:port/dbname

# 创建数据库引擎(同步模式)
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(
DATABASE_URL,
connect_args={"check_same_thread": False} # 仅SQLite需要
) # 创建所有表结构(相当于根据蓝图盖房子)
Base.metadata.create_all(bind=engine)

1.4 会话管理机制

数据库会话(Session)是工作单元模式的核心,管理所有数据库操作的生命周期。就像银行柜台办理业务,所有操作在窗口打开时开始,关闭时统一提交。

from sqlalchemy.orm import sessionmaker

# 创建会话工厂(相当于银行窗口)
SessionLocal = sessionmaker(
autocommit=False,
autoflush=False,
bind=engine
) # 依赖项注入(FastAPI最佳实践)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

2. 完整集成示例

2.1 用户管理API实现

from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from typing import Optional app = FastAPI() # Pydantic模型(数据验证层)
class UserCreate(BaseModel):
username: str
email: Optional[str] = None class UserResponse(UserCreate):
id: int
created_at: datetime # 创建用户端点
@app.post("/users/", response_model=UserResponse)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
# 检查用户名是否重复
db_user = db.query(User).filter(User.username == user.username).first()
if db_user:
raise HTTPException(status_code=400, detail="Username already registered") # 创建ORM对象
db_user = User(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user

2.2 查询接口实现

@app.get("/users/{user_id}", response_model=UserResponse)
def read_user(user_id: int, db: Session = Depends(get_db)):
user = db.query(User).filter(User.id == user_id).first()
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user

3. 常见问题解决方案

3.1 数据库会话报错处理

报错信息sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table

解决方案

  1. 检查是否调用Base.metadata.create_all(bind=engine)
  2. 确认数据库文件路径正确
  3. 确保模型类正确定义了__tablename__

3.2 数据验证错误

报错信息422 Unprocessable Entity,请求体验证失败

排查步骤

  1. 检查Pydantic模型字段类型定义
  2. 验证请求Content-Type是否为application/json
  3. 使用Swagger UI测试接口,观察请求示例格式

课后Quiz

问题1:当需要添加用户年龄字段时,应如何修改模型?

A. 同时在SQLAlchemy模型和Pydantic模型中添加字段

B. 只需修改SQLAlchemy模型

C. 需要同时修改SQLAlchemy模型和Pydantic模型,并执行数据库迁移

答案:C

解析:SQLAlchemy模型负责数据库结构,Pydantic模型负责数据验证。新增字段需两者同时修改,并通过迁移工具更新数据库表结构。

问题2:如何防止用户注册时邮箱重复?

A. 在数据库层面设置唯一约束

B. 在业务逻辑中先查询是否存在

C. 同时使用A和B

答案:C

解析:数据库唯一约束是最终保障,业务逻辑中的检查能提前发现错误,提升系统友好性。两者结合是最佳实践。

4. 高级配置技巧

4.1 复合索引优化

from sqlalchemy import Index

class Product(Base):
__tablename__ = 'products'
id = Column(Integer, primary_key=True)
name = Column(String(100))
category = Column(String(50))
price = Column(Integer) # 创建复合索引(名称+类别)
__table_args__ = (
Index('idx_name_category', 'name', 'category'),
)

4.2 事务管理示例

def transfer_funds(sender_id, receiver_id, amount, db):
try:
sender = db.query(User).get(sender_id)
receiver = db.query(User).get(receiver_id) if sender.balance < amount:
raise ValueError("Insufficient balance") sender.balance -= amount
receiver.balance += amount db.commit()
except:
db.rollback()
raise

运行服务:

uvicorn main:app --reload

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

往期文章归档:

FastAPI与SQLAlchemy同步数据库集成的更多相关文章

  1. FastAPI快速查阅

    官方文档主要侧重点是循序渐进地学习FastAPI, 不利于有其他框架使用经验的人快速查阅 故本文与官方文档不一样, 并补充了一些官方文档没有的内容 安装 包括安装uvicorn $pip instal ...

  2. FastAPI:一个测试人员视角的教程

    前言 教程肯定谈不上了,主要还是就自己的理解分享内容而已 内容是连官方文档的基础教程都没涵盖起的 建议直接看官方文档 以个人视角来分享,希望各位通过这个可以写接口了 需要自取 完整视频链接:https ...

  3. FastAPI 学习之路(三十二)创建数据库

    在大型的web开发中,我们肯定会用到数据库操作,那么FastAPI也支持数据库的开发,你可以用 PostgreSQL MySQL SQLite Oracle 等 本文用SQLite为例.我们看下在fa ...

  4. 2020年是时候更新你的技术武器库了:Asgi vs Wsgi(FastAPI vs Flask)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_167 也许这一篇的标题有那么一点不厚道,因为Asgi(Asynchronous Server Gateway Interface) ...

  5. Python 【第六章】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  6. SQLAlchemy文档翻译

    想记录一下SQLAlchemy的入门学习,然后突发奇想觉得:为什么不直接翻译一下文档呢?于是顺手查了查怎么使用Gitbook,2333 于是就在Github开了项目,然后导入了Gitbook,开始写. ...

  7. Python操作Redis、Memcache、RabbitMQ、SQLAlchemy

    Python操作 Redis.Memcache.RabbitMQ.SQLAlchemy redis介绍:redis是一个开源的,先进的KEY-VALUE存储,它通常被称为数据结构服务器,因为键可以包含 ...

  8. Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

  9. Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

    Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy   Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用 ...

  10. Python操作 Memcache、Redis、RabbitMQ、SQLAlchemy

    Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度 ...

随机推荐

  1. 「NOIP2024」 树上查询

    update 2024/12/28 题目描述 给定一棵树,每次询问区间 \([l,r]\) 的 \[\max_{l \le l' \le r' \le r \land r' - l' + 1 \ge ...

  2. DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」

    前言 最近 DeepSeek 狠狠刷了一波屏,国产大模型真的越来越厉害了,官方的服务器已经爆满了,以至于频繁出现反应迟缓甚至宕机的情况,和两年多之前 ChatGPT 的遭遇颇为相似. 我已经好久没有本 ...

  3. MWC 2024丨中国电信柯瑞文:建设云网融合的新型数字基础设施

    2月27日,世界互联网大会在2024世界移动通信大会(MWC 2024)期间举办"算力网络"专题论坛.中国电信董事长柯瑞文作题为<建设云网融合的新型数字基础设施>的主旨 ...

  4. Q:群晖磁盘断电导致,无法访问系统分区

    1.群晖磁盘断电导致,无法访问系统分区 2.点击存储空间管理员-总览-点击修复 3.存储空间-文件系统检查-重启 4.重启后正常

  5. .Net 配置绑定 IOptions

    准备   首先准备下appsettins.json以及目标类   appsettins.json "StudentSettings": { "Id": 1023 ...

  6. AI图像翻译

    在当今互联互通的世界中,快速准确地翻译图像中的文本的能力非常宝贵.无论您是商务人士.教育工作者.设计师还是内容创作者,Visual Paradigm Online 的 AI 图像翻译器都能提供强大的解 ...

  7. Linux Centos7 下使用yum安装redis

    更改yum源 由于CentOS官方yum源里面没有Redis,这里我们需要安装一个第三方的yum源,这里用了Fedora的epel仓库: yum install epel-release 安装redi ...

  8. PowerShell实现读取照片并做灰度处理

    Powershell一直是我的学习目标.做一个小例子.PowerShell实现读取照片并做灰度处理.还想要保存这张灰度照片并直接打开查看. 分析需求: [读取照片]  需要借助.net framewo ...

  9. DeepSeek 不太稳定?那就搭建自己的 DeepSeek 服务

    概述 DeepSeek-R1 发布 DeepSeek 在 2025 年给我们送来一份惊喜,1 月 20 号正式发布第一代推理大模型 DeepSeek-R1.这个模型在数学推理.代码生成和复杂问题解决等 ...

  10. 【日常运维笔记】linux系统修改密码

    1.问题描述:xshll无法正常登录服务器,使用宝塔系统后台linux工具修改密码,重启服务器,依然无法登录,怀疑密码未重置成功,我们登录root,重置密码. 使用命令passwd修改密码,需要注意的 ...