必须安装pymysql或mysqlclient驱动才能连接mysql,sqlalchemy仅是orm层;推荐pymysql(pip install pymysql),url写为mysql+pymysql://,密码含特殊字符需quote_plus编码,建表须显式设__tablename__和主键,操作后需commit。

直接用 SQLAlchemy 连 MySQL 没问题,但必须配对使用 PyMySQL 或 mysqlclient 作为底层驱动,否则会报 ModuleNotFoundError: No module named 'MySQLdb' 或类似连接失败错误。
安装对应驱动和 SQLAlchemy
Flask 本身不带数据库驱动,SQLAlchemy 也只是 ORM 层,真正发网络请求的是下层驱动:
- 推荐用
PyMySQL:纯 Python 实现,安装快,兼容性好,执行pip install PyMySQL - 若选
mysqlclient(C 扩展,性能略高),需先装系统依赖(如 Ubuntu 上sudo apt-get install python3-dev default-libmysqlclient-dev),再pip install mysqlclient -
SQLAlchemy和Flask-SQLAlchemy二选一即可;新手建议用Flask-SQLAlchemy,它自动集成 Flask 生命周期(如请求结束自动清理 session)
配置数据库 URL 时注意驱动名和参数写法
URL 格式是关键,错一个字符就连不上。常见写法:
mysql+pymysql://username:password@localhost:3306/dbname?charset=utf8mb4
注意点:
- 协议头必须是
mysql+pymysql(用PyMySQL)或mysql://(用mysqlclient),不能只写mysql - 密码里含特殊字符(如
@、/)必须用urllib.parse.quote_plus()编码,否则解析 URL 会出错 -
charset=utf8mb4要显式加上,否则存 emoji 或四字节 UTF-8 字符会报错 - 生产环境建议加
connect_timeout=10和read_timeout=30参数防卡死
定义模型时别漏掉 __tablename__ 和主键
Flask-SQLAlchemy 不会自动推导表名,也不允许无主键模型:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
from flask_sqlalchemy import SQLAlchemy <p>db = SQLAlchemy()</p><p>class User(db.Model): <strong>tablename</strong> = 'users' # 必须显式声明,否则默认转成小写下划线(如 user → user) id = db.Column(db.Integer, primary_key=True) # 必须有且仅有一个 primary_key=True name = db.Column(db.String(80), nullable=False)</p>
常见坑:
- 没写
__tablename__,结果查User.query.all()却返回空——其实是查了不存在的user表 - 字段类型用
db.String而不是str,用db.DateTime而不是datetime.datetime -
nullable=False对应 MySQL 的NOT NULL,但不加不代表可为 NULL,得看数据库实际约束
初始化和查询要匹配应用上下文
在 Flask 外(比如单独脚本、shell 或单元测试)直接调 User.query.all() 会报 RuntimeError: Application not registered on db instance:
- 正确做法:用
app.app_context()包一层,例如启动 shell 后先运行app.app_context().push() - Web 请求中没问题,因为 Flask 自动管理上下文;但 CLI 命令、定时任务、异步任务(如 Celery)都得手动搭上下文
- 建表别用
db.create_all()直接在线上跑,容易误删数据;推荐用flask-migrate做版本化迁移
最常被忽略的一点:MySQL 的 autocommit 默认关闭,INSERT/UPDATE/DELETE 后必须显式 db.session.commit(),否则事务一直挂起,别人查不到新数据,自己也看不到变更。这个行为和 SQLite 完全不同,容易踩空。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










