Python执行MySQL带SUM聚合的INSERT语句报PlayerName无默认值错误
执行求和插入时报MySQL 1364错误的排查与修复
问题现象
直接在MySQL客户端执行同一条求和插入SQL可正常得到返回结果,但写入Python脚本通过mysql-connector执行时触发报错:mysql.connector.errors.DatabaseError: 1364 (HY000): Field 'PlayerName' doesn't have a default value
涉及的原始代码逻辑
表结构定义
HAND_HISTORY_DB_TABLES['Hands'] = ( "CREATE TABLE `Hands` (" " `HandResults` float" ") ENGINE=InnoDB" ) HAND_HISTORY_DB_TABLES['Players'] = ( "CREATE TABLE `Players` (" " `PlayerName` varchar(16) PRIMARY KEY," " `PlayerResults` float" ") ENGINE=InnoDB" )
报错的执行方法
def insert_player_results(self): """ 插入玩家对局累计收益 :return: """ try: cursor.execute("INSERT INTO Players (PlayerResults) SELECT ROUND(SUM(HandResults), 2) FROM Hands") sql_connection.commit() print("Player Results inserted succesfully") except mysql.IntegrityError as err: print(f"Error: {err}") # 方法实际调用 plyr.insert_player_results()
报错根因
核心问题是编写的INSERT语句缺失了主键字段的合法赋值:
Players表的PlayerName是主键字段,定义为varchar(16)类型,既没有设置默认值,也不允许为空。- 当前执行的插入逻辑只给
PlayerResults字段赋值,没有给PlayerName传递合法值,完全不满足主键字段的非空约束要求。 - 直接在MySQL客户端执行同语句可正常运行,是因为客户端连接的MySQL实例未开启严格SQL模式,会对无默认值的非空字段隐式填充空值绕过校验;而Python连接默认匹配服务端的严格模式配置,遇到缺失非空字段值的场景会直接抛出1364错误。
对应修复方案
结合实际业务存储逻辑选择匹配的修正方式:
- 若需求是在
Players表中写入一条全量对局收益的汇总记录:需要给主键PlayerName传入唯一标识值,修正后的SQL为:INSERT INTO Players (PlayerName, PlayerResults) SELECT 'TOTAL_GRAND_SUM', ROUND(SUM(HandResults), 2) FROM Hands - 若需求是为每个已有玩家匹配对应的对局累计收益:当前
Hands表缺少玩家标识关联字段,需先给Hands表补充PlayerName关联列,再通过关联更新的方式写入对应玩家的收益值,无需插入新行,示例SQL为:UPDATE Players p INNER JOIN ( SELECT PlayerName, ROUND(SUM(HandResults), 2) AS total_result FROM Hands GROUP BY PlayerName ) hand_sum ON p.PlayerName = hand_sum.PlayerName SET p.PlayerResults = hand_sum.total_result - 不推荐为了绕过报错给
PlayerName设置默认值,会破坏主键唯一、非空的基础设计规则,后续容易出现数据一致性问题。
内容的提问来源于stack exchange,提问作者Luck Box
相关产品推荐
相关产品推荐

