数据库基础与 SQLAlchemy 简介
本教程共 50 篇 · 第 32 篇 · 更新于 2026-08-12 · 约 8 分钟阅读
本节目标:搞懂「为什么要用数据库」、关系型与文档型数据库有什么不同、ORM 是什么,以及 SQLAlchemy 在 FastAPI 里如何帮你省去手写 SQL 的麻烦。
做接口光靠内存变量是不够的。服务一重启,内存里的数据就没了。真实项目里,用户名、订单、文章这些内容都要长久保存,这就要用到数据库。FastAPI 本身不绑定任何数据库,你想用哪个都行,但 SQLAlchemy 是社区里最常被选中的那个。
32-1 为什么一定需要数据库
先想一个场景。你写了个注册接口,用户提交姓名和邮箱。如果你把数据存在 Python 的列表里,程序一旦重启,列表清空,所有用户全部丢失。这显然不行。
数据库就是专门用来「长期、可靠地保存数据」的软件。它把数据写到磁盘文件里,断电、重启都不会丢。同时它还提供查找、统计、并发控制这些能力,让你用很少的代码就能管好大量数据。
NoteFastAPI 只是一个 Web 框架,负责接收请求、返回响应。它不管数据存哪里,数据库是「外挂」组件,通过专门的库来连接。
32-2 关系型数据库长什么样
关系型数据库(Relational Database)用「表」来组织数据,是当下最主流的一类。你可以把它想象成很多张 Excel 表格。
比如一张 users 表:
| id | name | |
|---|---|---|
| 1 | 小明 | a@x.com |
| 2 | 小红 | b@x.com |
每一行是一条记录,每一列是一个字段。不同表之间还能通过「外键」建立关系。比如 orders 表里的 user_id 指向 users 表的 id,就知道这笔订单属于谁。
这类数据库用 SQL(结构化查询语言)来操作,查询写法是标准化的,比如 SELECT * FROM users WHERE id = 1。常见的关系型数据库有:
- SQLite:单文件,Python 自带支持,适合学习和小项目。
- PostgreSQL:功能强、生态好,生产环境首选。
- MySQL / MariaDB:同样流行。
- Oracle、SQL Server:企业级商业数据库。
Tip本书示例默认用 SQLite,因为它零配置、一个文件就搞定,复制代码就能跑。等你上生产,把连接字符串换成 PostgreSQL 即可,业务代码几乎不用改。
32-3 文档型数据库又是什么
另一大类叫 NoSQL 数据库,其中「文档型」最常见,代表是 MongoDB。它不存表格,而是存「文档」——本质就是一段 JSON 风格的数据。
还是存用户,MongoDB 里的一条记录长这样:
{
"name": "小明",
"email": "a@x.com",
"tags": ["vip", "new"]
}
注意它没有固定列,每个文档的字段可以不一样,想加就加,非常灵活。这对结构经常变动的数据很友好,比如日志、配置、用户画像。
那该选哪种?一句话:数据之间关系多、要求强一致(如订单、账户),用关系型;数据结构松散、追求灵活扩展(如评论、埋点),用文档型。FastAPI 两种都能接,本章先聚焦关系型,MongoDB 留到第 37 章。
32-4 什么是 ORM
直接写 SQL 字符串操作数据库,有几个麻烦:SQL 语句是字符串,写错了只有运行时才发现;查询结果返回的是元组,要自己转成对象;换数据库时 SQL 语法可能要改。
ORM(Object Relational Mapper,对象关系映射)就是来解决这些问题的。它让你用「写 Python 类」的方式定义表,用「操作对象」的方式读写数据,底下帮你翻译成 SQL。
举例,不用 ORM 时你要写:
# 手写 SQL,容易出错,返回值不好用
cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)", ("小明", "a@x.com"))
用了 ORM,你写的是:
# 操作对象,直观且类型安全
user = User(name="小明", email="a@x.com")
session.add(user)
ORM 自动把对象变成 SQL 去执行,再把查回来的行变回对象。常见的 ORM 有 Django ORM、Peewee,以及我们这章重点讲的 SQLAlchemy。
NoteORM 不是银弹。特别复杂的统计查询,直接写 SQL 反而更清楚。但日常增删改查,ORM 能大幅提升开发效率。
32-5 SQLAlchemy 是什么,2.0 风格长啥样
SQLAlchemy 是 Python 里最成熟的数据库工具库,它分两层:底层 Core 负责拼 SQL、连数据库;上层 ORM 提供对象映射。FastAPI 作者还基于它做了 SQLModel,但对初学者来说,先把 SQLAlchemy 本身学透更扎实。
SQLAlchemy 在 2.0 版本统一了风格。下面用 2.0 写法定义一个最简单的用户表,你先有个印象,第 33 章会细讲:
from sqlalchemy import String, create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
# 2.0 风格:用 DeclarativeBase 作为所有模型的基类
class Base(DeclarativeBase):
pass
# 用 Mapped[类型] + mapped_column 描述字段,类型清晰
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(30))
email: Mapped[str] = mapped_column(String(100), unique=True)
# 引擎负责连库,Session 负责一次会话的交互
engine = create_engine("sqlite:///./demo.db")
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(User(name="小明", email="a@x.com"))
session.commit()
这段代码里出现的 Base、Mapped、mapped_column、Session、create_engine,后面几章会逐个拆开讲。你只要先记住:定义一张表,就是写一个继承 Base 的 Python 类。
TipSQLAlchemy 2.0 同时兼容旧写法(
Column(Integer, primary_key=True))。本书统一用 2.0 的新写法Mapped[...],类型提示更清楚,编辑器补全也更智能。
32-6 为什么 FastAPI 常用 SQLAlchemy
FastAPI 跟 SQLAlchemy 特别搭,原因有几点。
第一,FastAPI 是基于 ASGI 的异步框架,而 SQLAlchemy 2.0 提供了完整的异步支持(AsyncSession、create_async_engine),两者配合顺滑,能写出不阻塞的高并发接口。第 36 章专门讲。
第二,FastAPI 重度依赖 Pydantic 做数据校验和接口文档。SQLAlchemy 的对象和 Pydantic 模型可以无缝衔接:查询得到 ORM 对象后,交给 Pydantic 的 from_attributes=True 配置,就能直接转成接口返回的数据结构。
第三,SQLAlchemy 支持几乎所有主流关系型数据库,切换成本低。而且它不依赖框架,你写好的模型和操作函数,在后台任务、定时脚本里也能直接复用。
Note官方文档现在主推 SQLModel(等于 SQLAlchemy + Pydantic 合体)。但 SQLModel 把两者概念揉在一起,反而容易让新手混淆。本书先用纯 SQLAlchemy 把基础打牢,理解更清楚,以后看 SQLModel 也毫不费力。
32-7 先把环境装好
开始写代码前,先装两个包:
pip install sqlalchemy
pip install "fastapi[standard]"
本书代码基线:FastAPI 0.141.1、Python 3.10 以上、Pydantic v2。后面所有示例都基于这个环境,默认用 async def 写路径操作,启动统一用 fastapi dev main.py。
Tip想跟着跑,建议新建一个文件夹,用虚拟环境安装依赖,避免污染全局 Python。SQLite 不需要额外装数据库服务,开箱即用。
这一章你建立了「数据库→关系型/文档型→ORM→SQLAlchemy」的整体认知。下一章我们动手连上数据库,并真正把表定义出来。