Flask-SQLAlchemy_数据库配置

1、基本概念(SQLAlchemy与Flask-SQLAlchemy)

SQLAlchemy 是 Python 生态中最具影响力的 ORM(对象关系映射)库,其设计理念强调 "框架无关性",支持在各类 Python 项目中独立使用,包括 Flask、Django 等 Web 框架,以及脚本工具、数据处理程序等。

ORM相关的介绍:主流编程语言中ORM工具全解析

Flask-SQLAlchemy 作为 SQLAlchemy 在 Flask 框架中的官方集成扩展,通过以下方式简化开发体验:

  • 自动绑定 Flask 应用上下文,实现数据库会话的生命周期管理
  • 提供基于 Flask 配置系统的统一参数管理
  • 优化数据库操作的异常处理与事务管理
  • 简化模型定义与查询语法

这种分层设计使开发者既能享受 SQLAlchemy 的强大功能,又能遵循 Flask 的开发范式。

2、支持的数据库

Flask-SQLAlchemy 基于 SQLAlchemy 提供广泛的数据库支持,主要包括:

  • SQLite(开发环境首选)
  • MySQL(企业应用主流选择)
  • PostgreSQL(复杂查询与数据分析场景)
  • SQL Server(Windows 平台集成)
  • Oracle(企业级数据系统)

通过统一的连接 URI 配置体系,开发者可以无缝切换不同数据库,无需修改业务代码

python 复制代码
# 配置示例:不同数据库的连接 URI
# SQLite
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

# MySQL (TCP 连接)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://user:password@host:3306/dbname'

# PostgreSQL
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@host:5432/dbname'

# SQL Server
app.config['SQLALCHEMY_DATABASE_URI'] = 'mssql+pyodbc://user:password@server/dbname?driver=ODBC+Driver+17+for+SQL+Server'

3、核心配置------SQLALCHEMY_DATABASE_URI【连接数据库】

如上所述可以连接多种数据库,这里以连接MySQL数据库为例。

3.1、标准 TCP 连接

标准 URI 格式为:数据库类型+驱动://用户名:密码@主机:端口/数据库名?参数

python 复制代码
# 用户名密码方式连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@hostname:3306/database_name?charset=utf8mb4'

参数说明:

  • mysql+pymysql:指定使用 PyMySQL 驱动(推荐)
  • charset=utf8mb4:建议始终添加以支持完整 Unicode 字符集
  • 使用环境变量存储敏感信息:
python 复制代码
import os
app.config['SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://{os.environ["DB_USER"]}:{os.environ["DB_PASSWORD"]}@{os.environ["DB_HOST"]}/database_name'

3.2、Unix Socket 本地连接

MySQL 服务器启用基于操作系统用户认证的auth_socket 插件,避免在代码或配置文件中存储数据库密码

格式为:数据库类型+驱动://用户名@数据库名?unix_socket地址

python 复制代码
# 通过 Unix Socket 进行本地连接(无需明文密码)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username@/database_name?unix_socket=/var/run/mysqld/mysqld.sock'

4、核心配置------SQLALCHEMY_ENGINE_OPTIONS【连接池配置(生产环境必备)】

4.1、连接池是什么?

SQLALCHEMY_ENGINE_OPTIONS 用于配置 SQLAlchemy 底层的 数据库连接池(Connection Pool) 行为。

连接池是数据库性能优化的核心组件,其作用是:复用数据库连接,避免频繁创建/销毁连接的开销(创建一个数据库连接通常需要 TCP 握手、SSL 协商、身份验证等步骤,耗时可达几十毫秒)。

4.2、为什么需要手动配置这些参数?

默认情况下,SQLAlchemy 会根据数据库类型自动选择连接池实现(如 SQLite 使用 NullPool,MySQL 使用 QueuePool),并提供一套通用默认值。但这些默认值可能无法满足生产环境的需求,例如:

  • 默认连接池大小较小(如 pool_size=5),高并发时会出现连接等待;
  • 未设置连接回收时间,可能导致数据库服务器主动关闭空闲连接(如 MySQL 的 wait_timeout 默认 8 小时),形成"僵尸连接"(连接已被数据库关闭,但应用仍认为可用);
  • 未开启连接前验证,获取到无效连接时会抛出异常(如 OperationalError: (2006, 'MySQL server has gone away'))。

因此,生产环境必须根据业务场景手动配置连接池参数,以平衡性能、稳定性和数据库负载。

4.3、核心参数详解

1. pool_size:连接池核心大小(长期保留的连接数)

  • 作用 :连接池初始化时创建的连接数,也是长期保持的最小连接数。当并发请求数小于等于 pool_size 时,直接复用现有连接,无需新建。
  • 默认值5(MySQL 等数据库的 QueuePool 默认值)。
  • 为什么需要调整
    • 若业务并发量高(如 Web 应用的 QPS 超过 100),默认的 5 个连接会导致大量请求排队等待;
    • 若设置过大(如超过数据库的 max_connections),会导致数据库负载过高,甚至拒绝新连接。
  • 建议值 :根据数据库的 max_connections(默认 151)和业务峰值并发量调整,通常设置为 CPU核心数 * 2(如 4 核 CPU 设为 8)。

2. max_overflow:连接池最大溢出数(临时扩展的连接数)

  • 作用 :当并发请求数超过 pool_size 时,连接池可以临时创建的额外连接数。这些连接在请求完成后会被逐步释放(回到 pool_size 大小)。
  • 默认值10QueuePool 默认值)。
  • 为什么需要调整
    • 若设置过小(如 max_overflow=0),高并发时会因无法扩展连接而报错(TimeoutError);
    • 若设置过大(如 max_overflow=100),可能导致数据库连接数爆炸(总连接数 = pool_size + max_overflow),超出数据库的 max_connections 限制。
  • 建议值 :根据数据库的 max_connections 剩余容量调整,通常设置为 pool_size * 2(如 pool_size=10 时设为 20)。

3. pool_recycle:连接回收时间(秒)

  • 作用:连接在池中存活的最长时间(从创建时开始计时)。超过该时间后,连接会被强制回收并重新创建,避免因数据库服务器主动关闭空闲连接导致的"僵尸连接"问题。
  • 默认值-1(永不回收,连接长期存活)。
  • 为什么需要调整
    • 许多数据库(如 MySQL)会配置 wait_timeout(默认 8 小时),超过该时间未活动的连接会被数据库主动关闭;
    • pool_recycle 未设置(或大于 wait_timeout),应用获取到已被数据库关闭的连接时,会抛出 OperationalError(如"MySQL server has gone away")。
  • 建议值 :小于数据库的 wait_timeout(如 MySQL 设为 3600 秒,即 1 小时)。

4. pool_timeout:获取连接的超时时间(秒)

  • 作用 :当连接池无可用连接时(所有连接都被占用且无法扩展 max_overflow),等待新连接释放的最长时间。超时后会抛出 TimeoutError
  • 默认值30 秒(QueuePool 默认值)。
  • 为什么需要调整
    • 若业务需要快速失败(如前端接口),可设置较小值(如 10 秒),避免长时间阻塞;
    • 若业务允许慢处理(如后台任务),可适当增大(如 60 秒)。
  • 建议值 :根据业务响应时间要求调整,通常保持默认 30 秒即可。

5. pool_pre_ping:连接前验证(避免僵尸连接)

  • 作用 :在从连接池获取连接前,先执行一次轻量级 SQL 查询(如 SELECT 1),验证连接是否有效。若无效,会重新创建连接。
  • 默认值False(不验证)。
  • 为什么需要调整
    • 即使设置了 pool_recycle,仍可能因网络波动、数据库重启等原因产生临时无效连接;
    • pool_pre_ping=True 可以"兜底"验证连接有效性,几乎完全避免僵尸连接问题(代价是每次获取连接增加约 1ms 延迟)。
  • 建议值 :生产环境建议设置为 True(尤其是数据库可能重启或网络不稳定时)。

4.4、示例

python 复制代码
# 优化生产环境连接池配置
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
    'pool_size': 10,                 # 连接池大小
    'max_overflow': 20,              # 最大溢出连接数
    'pool_recycle': 3600,            # 连接回收时间(秒)
    'pool_timeout': 30,              # 连接超时时间(秒)
    'pool_pre_ping': True            # 连接前验证(避免僵尸连接)
}

可以通过 MySQL 的状态变量Threads_connected 查看当前实际连接数,来判断参数设置多少为合适,SHOW STATUS LIKE 'Threads_connected';

相关推荐
草莓熊Lotso1 天前
C++ 方向 Web 自动化测试入门指南:从概念到 Selenium 实战
前端·c++·python·selenium
我是李武涯1 天前
PyTorch Dataloader工作原理 之 default collate_fn操作
pytorch·python·深度学习
大气层煮月亮1 天前
Oracle EBS ERP开发——报表生成Excel标准模板设计
数据库·oracle·excel
云和数据.ChenGuang1 天前
达梦数据库的命名空间
数据库·oracle
Kratzdisteln1 天前
【Python】绘制椭圆眼睛跟随鼠标交互算法配图详解
python·数学·numpy·pillow·matplotlib·仿射变换
maxruan1 天前
PyTorch学习
人工智能·pytorch·python·学习
三三木木七1 天前
mysql拒绝连接
数据库·mysql
蹦跶的小羊羔1 天前
sql数据库语法
数据库·sql
唐古乌梁海1 天前
【mysql】InnoDB的聚簇索引和非聚簇索引工作原理
数据库·mysql
我变秃了也没变强1 天前
pgsql配置密码复杂度策略
数据库·postgresql