当前位置:首页 > 云服务器 > 正文

Flask怎么用DBUtils模块连接数据库,步骤是什么?

Flask框架使用DBUtils模块连接数据库

在Flask应用开发中,数据库连接管理是影响性能和稳定性的关键环节,传统的每次请求时创建、使用后销毁连接的方式,在高并发场景下会导致频繁的连接开销,甚至耗尽数据库资源。DBUtils 模块提供了稳定的数据库连接池机制,能够有效复用连接,提升应用性能。

为什么需要连接池

  • 减少开销:创建数据库连接(TCP握手、认证等)是相对昂贵的操作,池化后只创建一次,后续请求复用。
  • 控制并发:限制最大连接数,避免数据库被过多连接压垮。
  • 提高响应速度:连接已就绪,直接使用,无需等待建立新连接。

DBUtils 简介

DBUtils 是 Python 的数据库连接池工具,支持两种模式:

模式 类名 特点
持久连接(每个线程独立) PersistentDB 为每个线程维护一个连接,线程安全,适合线程数固定的场景
共享连接池(线程间复用) PooledDB 所有线程共享一组连接,支持最大连接数、最小空闲连接等参数,更常用

在 Flask 中,通常使用 PooledDB,因为 Flask 的请求处理线程是动态分配的。

Flask怎么用DBUtils模块连接数据库,步骤是什么? 第1张

安装 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 的场景。

    Flask怎么用DBUtils模块连接数据库,步骤是什么? 第2张

    方面 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 等外部连接池中间件)。

    Flask怎么用DBUtils模块连接数据库,步骤是什么? 第3张

0