0

0

Peewee 默认覆盖 MySQL 严格模式:如何正确启用 SQL 严格校验

碧海醫心

碧海醫心

发布时间:2026-01-13 15:09:23

|

251人浏览过

|

来源于php中文网

原创

Peewee 默认覆盖 MySQL 严格模式:如何正确启用 SQL 严格校验

peewee 在连接 mysql 时默认强制设置 `sql_mode="pipes_as_concat"`,会覆盖数据库全局 strict mode(如 `traditional`),导致 `null=false` 字段缺失时不报错——本文详解原因及三种可靠修复方案。

Peewee 的 MySQL 驱动(MySQLDatabase 及其子类 MySQLConnectorDatabase)为兼容性考虑,在初始化连接时主动注入 sql_mode="PIPES_AS_CONCAT"(见源码第 4147 行)。该行为会完全覆盖 MySQL 服务端配置的全局 sql_mode(例如通过 SET GLOBAL sql_mode = 'TRADITIONAL' 启用的严格模式),从而导致本应被拒绝的不完整 INSERT 操作(如省略 NOT NULL 字段)静默成功,插入默认值(如空字符串、0000-00-00 时间等),严重违背数据完整性预期。

这与 SQLite 行为形成鲜明对比:SQLite 下 Peewee 会主动校验 NOT NULL 约束并抛出 IntegrityError;而 MySQL 下因 SQL 模式被覆盖,校验权交还给了数据库驱动层,却未能触发严格约束。

✅ 解决方案一:显式指定完整 sql_mode(推荐)

在创建 MySQLDatabase 实例时,直接传入所需的严格模式组合(需包含 PIPES_AS_CONCAT 以保证 Peewee 功能正常):

debug_db = MySQLDatabase(
    database='debug_db',
    user='DEBUG',
    host='localhost',
    password='secret',
    sql_mode='STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT'
)
? 提示:TRADITIONAL 是 MySQL 内置别名,等价于 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL。若需精简,可选用 STRICT_TRANS_TABLES,PIPES_AS_CONCAT —— 它是兼顾安全与兼容的最小严格集。

✅ 解决方案二:复用全局模式 + 追加 PIPES_AS_CONCAT

若希望继承 MySQL 服务端全局 sql_mode 并仅追加 Peewee 所需特性,可禁用 Peewee 的 sql_mode 覆盖,并通过 init_command 动态拼接:

天谱乐
天谱乐

唱鸭旗下AI音乐创作平台,为您提供个性化音乐创作体验!

下载
debug_db = MySQLDatabase(
    database='debug_db',
    user='DEBUG',
    host='localhost',
    password='secret',
    sql_mode=None,  # 关键:禁用 Peewee 默认覆盖
    init_command="SET sql_mode = (SELECT CONCAT(@@sql_mode, ',PIPES_AS_CONCAT'));"
)

⚠️ 注意:init_command 在连接建立后立即执行,依赖 @@sql_mode 变量,确保 MySQL 版本 ≥ 5.7.6(推荐 ≥ 8.0)。

✅ 解决方案三:使用 playhouse.pool.PooledMySQLDatabase(生产环境增强)

对于高并发场景,建议结合连接池与显式模式控制:

from playhouse.pool import PooledMySQLDatabase

debug_db = PooledMySQLDatabase(
    database='debug_db',
    user='DEBUG',
    host='localhost',
    password='secret',
    max_connections=20,
    stale_timeout=300,
    sql_mode='STRICT_TRANS_TABLES,PIPES_AS_CONCAT'
)

⚠️ 重要注意事项

  • 不要依赖 null=False 的 Python 层校验:Peewee 不会在 .save() 前主动检查 None 值是否违反非空约束(除非字段显式赋 None,此时会触发 IntegrityError);
  • default=None 是陷阱:这是 Peewee 所有字段的默认值,不代表“数据库默认值”,而是“无默认值”——必须由数据库或显式 default=/server_default= 提供;
  • 验证是否生效:连接后执行 SELECT @@sql_mode; 确认实际生效的模式;
  • 测试用例必备:在单元测试中模拟缺失必填字段场景(如 Person.create(first_name='Alice')),断言应抛出 peewee.IntegrityError。

通过以上任一方式正确配置 sql_mode,即可让 MySQL 严格模式真正生效,使 Peewee 的数据写入行为与数据库约束保持一致,从根本上保障数据质量与业务逻辑可靠性。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

749

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

635

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

758

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

618

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1262

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

706

2023.08.11

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

1

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.7万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 787人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号