我先把结论放在前面:如果你正在用Flask做后端开发,并且已经到了需要跟数据库打交道的阶段,那么这一篇几乎是绕不过去的必修课。标题里的“ORM增删改查”这几个字,核心价值在于帮你摆脱手写SQL的重复劳动,让数据操作变成纯粹的Python对象操作。这篇文章会把Flask连接MySQL的完整路径、ORM选型理由、增删改查的落地写法以及几个容易翻车的隐藏细节全部捋一遍,适合刚学完Flask基础路由和模板、准备进入数据层开发的初学者,也适合写过一些原生SQL但对SQLAlchemy体系不熟、想系统性补齐认知的开发者。
1. 为什么绕不开ORM:先想清楚再动手
进入代码之前,我觉得有必要先把“为什么用ORM”这个问题聊透。因为很多初学者要么觉得ORM是多余的抽象,要么觉得它很神秘,这两个极端都不太健康。
1.1 直接写SQL的问题在哪
当你的项目只有一张表、两三个查询语句的时候,直接用pymysql写原生SQL确实完全够用,代码还直白。但一旦表多起来,比如一个记账系统里有用户表、账目表、分类表、预算表,你很快就会遇到几件事:
- 每次查询都要手动写SQL字符串,拼接条件时稍微不注意就会把字符串引号搞乱。
- 查询结果是一堆字典或者元组,字段取值全靠字符串下标或者
row["字段名"],写起来非常啰嗦。 - 建表、改表结构、同步表结构全靠手工维护SQL脚本,版本一多就对不上。
- 代码里到处散落着SQL语句,一旦字段改名,你要全文搜索替换,很容易漏。
ORM(对象关系映射)解决的就是这些问题。它的思路很简单:把数据库里的一行数据映射成一个Python对象,把一张表映射成一个类,把增删改查操作映射成方法调用。你不需要纠结表结构和SQL语句,只需要操作对象本身。
1.2 为什么选SQLAlchemy而不是其他
Python生态里ORM方案并不算多,主流可选的有SQLAlchemy、Peewee,以及Django自带的ORM。Flask本身是一个微框架,不强制绑定ORM,所以社区最常见的选择就是SQLAlchemy。原因很实在:
- SQLAlchemy是独立于框架的,不绑定Flask,后续就算换框架你的数据模型也能带走。
- 它对复杂查询的支持非常强,子查询、联合查询、聚合函数、窗口函数这些都能写。
- 有完善的迁移工具Alembic配合,表结构变更可以像Git一样版本化管控。
- 社区资料多,遇到坑基本都能搜到解决方案。
Peewee虽然更轻量、上手更快,但在复杂项目里后期约束比较多,而且生态明显不如SQLAlchemy。Django的ORM是好东西,但它是跟着Django走的,没法单独拿来给Flask用。所以Flask项目的标准答案,基本就是SQLAlchemy。
1.3 Flask-SQLAlchemy与SQLAlchemy的关系
这里有一个非常常见的混淆点。SQLAlchemy是底层的ORM库,而Flask-SQLAlchemy是它的一个Flask扩展封装。封装的核心价值在于:
- 把
db.session和db.Model直接挂到Flask应用上,省掉手动创建Session、绑定引擎的样板代码。 - 让
db.create_all()可以自动根据模型类建表。 - 统一管理数据库会话的生命周期,应用上下文中的请求结束时会自动清理。
所以你只需要安装flask-sqlalchemy,它会把底层的SQLAlchemy一起带过来,不用另外装。这个封装已经足够覆盖绝大多数项目场景,没必要绕过它直接用原生的SQLAlchemy给自己找麻烦。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目接入:从安装MySQL到跑通第一条连接
这一步的坑,说实话比后面的代码多得多。很多人在写ORM代码前就已经被环境卡住两天了。我不打算把MySQL安装教程展开成一整篇,只把最容易犯错、影响后续使用的关键点筛出来讲。
2.1 MySQL安装与基础配置
MySQL的安装方式因操作系统不同差异很大,但有几个通用原则值得注意:
- MySQL 8.0是当前主流版本,写法和5.7有不少差异,特别是加密插件和字符集方面。
- 安装时记得设置root密码,并且注意密码的认证方式。MySQL 8.0默认使用
caching_sha2_password,部分Python驱动对这个认证方式支持得不好,这是一个巨大的坑。 - 安装完成后,建一个专用数据库,比如
blog_db或book_db,避免什么表都堆在系统库里。
建库时我强烈建议显式指定字符集:
sql复制CREATE DATABASE IF NOT EXISTS blog_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
为什么要用utf8mb4而不是utf8?因为MySQL的utf8其实是假的,它最多只能存3字节的字符,像Emoji表情这类4字节字符会直接报错。现在任何新项目都应该直接用utf8mb4,别给自己埋雷。
2.2 驱动选型:PyMySQL还是mysqlclient
Python要跟MySQL通信,中间需要一层数据库驱动。常见的选择有两个:
| 驱动 | 优点 | 缺点 |
|---|---|---|
| PyMySQL | 纯Python实现,安装方便,跨平台 | 性能略低于C扩展 |
| mysqlclient | C扩展,性能好 | Windows下安装容易报错,需要编译环境 |
我的建议是开发阶段直接用PyMySQL,省心省事。如果你追求极致性能并且部署环境是Linux,后续再切换到mysqlclient也不难。切换只需要改一下连接URI里的驱动名,数据模型完全不需要动。
安装PyMySQL:
bash复制pip install pymysql
另外建议提前安装cryptography库,因为PyMySQL在连接MySQL 8.0时,涉及到caching_sha2_password认证需要它:
bash复制pip install cryptography
这个坑我在实际项目中踩过不止一次。如果漏装,你会遇到一个看起来很莫名其妙的连接报错,其实根因就是密码认证过程中需要这个库。
2.3 在Flask里配置数据库连接
安装好依赖后,就可以在Flask应用里配置连接了。配置项的核心是SQLALCHEMY_DATABASE_URI,它决定了SQLAlchemy连哪个数据库。URI的格式是:
code复制dialect+driver://username:password@host:port/database?charset=utf8mb4
对应到我们的场景就是:
python复制app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+py
