Flask-SQLAlchemy

06-01 1080阅读

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 配置体系,开发者可以无缝切换不同数据库,无需修改业务代码

      # 配置示例:不同数据库的连接 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 格式为:数据库类型+驱动://用户名:密码@主机:端口/数据库名?参数

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

      参数说明:

      • mysql+pymysql:指定使用 PyMySQL 驱动(推荐)
      • charset=utf8mb4:建议始终添加以支持完整 Unicode 字符集
      • 使用环境变量存储敏感信息:
        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地址

        # 通过 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'))。

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

          Flask-SQLAlchemy
          (图片来源网络,侵删)

          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 大小)。
              • 默认值:10(QueuePool 默认值)。
              • 为什么需要调整:
                • 若设置过小(如 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、示例

                              # 优化生产环境连接池配置
                              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';

                              Flask-SQLAlchemy
                              (图片来源网络,侵删)
                              Flask-SQLAlchemy
                              (图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码