Flask怎么用DBUtils模块连接数据库,步骤是什么?
- 云服务器
- 2026-07-25
- 6
Flask框架使用DBUtils模块连接数据库
在Flask应用开发中,数据库连接管理是影响性能和稳定性的关键环节,传统的每次请求时创建、使用后销毁连接的方式,在高并发场景下会导致频繁的连接开销,甚至耗尽数据库资源。DBUtils 模块提供了稳定的数据库连接池机制,能够有效复用连接,提升应用性能。
为什么需要连接池
- 减少开销:创建数据库连接(TCP握手、认证等)是相对昂贵的操作,池化后只创建一次,后续请求复用。
- 控制并发:限制最大连接数,避免数据库被过多连接压垮。
- 提高响应速度:连接已就绪,直接使用,无需等待建立新连接。
DBUtils 简介
DBUtils 是 Python 的数据库连接池工具,支持两种模式:
| 模式 | 类名 | 特点 |
|---|---|---|
| 持久连接(每个线程独立) | PersistentDB | 为每个线程维护一个连接,线程安全,适合线程数固定的场景 |
| 共享连接池(线程间复用) | PooledDB | 所有线程共享一组连接,支持最大连接数、最小空闲连接等参数,更常用 |
在 Flask 中,通常使用 PooledDB,因为 Flask 的请求处理线程是动态分配的。

安装 DBUtils
pip install DBUtils
在 Flask 中使用 DBUtils
初始化连接池
通常将连接池作为应用全局对象,在应用启动时创建,以 MySQL 为例(使用 pymysql 驱动):
from flask import Flask, g from DBUtils.PooledDB import PooledDB import pymysql app = Flask(__name__) app.config['DB_HOST'] = 'localhost' app.config['DB_PORT'] = 3306 app.config['DB_USER'] = 'root' app.config['DB_PASSWORD'] = 'password' app.config['DB_NAME'] = 'myapp' app.config['DB_POOL'] = { 'maxconnections': 10, # 最大连接数 'mincached': 2, # 初始化时创建的连接数 'maxcached': 5, # 最大空闲连接数 'blocking': True, # 无可用连接时是否阻塞等待 'maxusage': None, # 单个连接最大复用次数 'setsession': [], # 会话参数 } def get_db(): if 'db' not in g: # 创建连接池(全局唯一) pool = PooledDB( creator=pymysql, host=app.config['DB_HOST'], port=app.config['DB_PORT'], user=app.config['DB_USER'], password=app.config['DB_PASSWORD'], database=app.config['DB_NAME'], app.config['DB_POOL'] ) # 从池中获取连接 g.db = pool.connection() return g.db @app.teardown_appcontext def close_db(error): if 'db' in g: g.db.close() # 归还连接到池,不是真正关闭
在视图函数中使用
@app.route('/users') def get_users(): conn = get_db() cursor = conn.cursor() cursor.execute('SELECT FROM users') users = cursor.fetchall() cursor.close() return {'users': users}
注意事项
- 连接归还:close() 方法实际将连接归还给池,而不是销毁,务必在请求结束时调用(如
teardown_appcontext)。
- 线程安全:PooledDB 内部处理了线程同步,可以直接使用。
- 异常处理:如果连接失效(如数据库重启),池会自动创建新连接,但建议在代码中捕获异常并重试。
- maxconnections:根据数据库最大连接数和应用并发量设定,一般设为 10~50。
- mincached:预创建连接数,避免启动时慢,通常设为 2~5。
- blocking:设为 True 让请求等待可用连接,而不是立即报错。
- maxusage:定期重建连接,避免长时间占用导致连接状态异常。
配置优化建议
与 Flask-SQLAlchemy 的对比
Flask 官方推荐使用 Flask-SQLAlchemy,它内置了连接池(基于 SQLAlchemy 的 QueuePool),但 DBUtils 更加轻量,适合直接使用原生 SQL 或简单 ORM 的场景。

| 方面 | DBUtils + 原生驱动 | Flask-SQLAlchemy |
|---|---|---|
| 学习曲线 | 低,只需理解连接池 | 中,需掌握 ORM 概念 |
| 灵活性 | 高,可完全控制 SQL | 受 ORM 限制 |
| 内置功能 | 仅连接池 | ORM、迁移、会话管理 |
| 适用场景 | 小型项目、性能敏感 | 大型项目、团队协作 |
常见问题
Q: 连接池中的连接会被关闭吗?
A: 默认不会自动关闭,但可以通过 maxusage 或 maxage 参数设置最大复用次数或存活时间,达到后池会销毁该连接并创建新连接。
Q: 为什么使用 g 对象存储连接?
A: Flask 的 g 上下文是请求级别的,可以确保每个请求获取的连接互不干扰,且能在 teardown_appcontext 中统一归还。
相关问题与解答
问题1:DBUtils 连接池中的连接在请求结束后为什么不能直接调用 conn.close() 关闭,而是需要归还?
解答:
DBUtils 连接池中的 connection 对象是对底层数据库连接的封装,当调用 close() 时,实际上不是真正关闭与数据库的 TCP 连接,而是将连接对象标记为空闲,并归还给池,供后续其他请求复用,如果直接关闭(如使用 conn.real_close() 或 pymysql 的 close()),该连接会从池中移除,池需要重新创建新连接,失去了连接池减少开销的意义,在 teardown_appcontext 中调用 g.db.close() 是标准做法,它会触发池的归还逻辑。
问题2:在多进程(如 Gunicorn 多 worker)场景下,DBUtils 连接池是否仍然有效?
解答:
DBUtils 的 PooledDB 是多线程安全的,但不是多进程安全的,每个进程都会独立维护自己的连接池,如果有多个 worker 进程,每个进程都会创建自己的池,总连接数会乘以进程数,这可能导致数据库连接数超过预期,需要合理配置每个进程的 maxconnections,并在数据库端设置最大连接限制,如果需要跨进程共享连接池,需使用其他方案(如 PgBouncer 或 ProxySQL 等外部连接池中间件)。
