Python执行带NOT EXISTS的去重INSERT语句未生效?Workbench运行正常
同一句SQL在Workbench正常、Python执行失效的核心原因
1. 未手动提交事务(最高发问题)
mysql.connector驱动默认关闭自动提交开关,所有通过游标执行的INSERT/UPDATE/DELETE类DML操作,只会暂存于当前会话的未提交事务中,不会直接持久化到数据库。
MySQL Workbench的默认连接配置是开启自动提交的,因此同一句SQL在工具内执行后会立刻生效,完全符合预期。你的Python代码中执行完SQL后既没有调用db.commit()手动提交变更,也没有在初始化连接时设置自动提交,程序运行结束后连接被回收,未提交的插入操作会被MySQL自动回滚,最终正式表没有任何数据变动,直观表现就是SQL逻辑失效。
2. 表结构不匹配导致静默执行失败
你的INSERT语句没有显式指定目标表的插入字段,完全依赖SELECT *的列顺序和正式表game_results的列顺序一一对应:
- pandas通过
to_sql写入new_game_results临时表时,列顺序和清洗后的DataFrame列顺序完全一致,如果清洗过程中删除了全空列导致列和正式表的列顺序错位,会直接触发“列数与值不匹配”的插入报错 - 你在Workbench调试SQL时用的临时表结构,可能是之前手动调整过、和正式表完全对齐的版本,但Python流程自动生成的临时表结构不一定和调试版本一致,导致同一句SQL在不同结构下执行结果异常
3. 去重关联的比较规则不一致
如果去重关联用到的date、HomeTeam字段存在隐式属性差异,会直接导致去重逻辑失效:
- 比如pandas写入临时表时,
date字段被存为字符串类型,但正式表的date字段是DATE类型,关联比较时因为两边的类型转换规则差异,本应匹配的记录被判定为不相等,最终出现重复插入或漏插入 - 比如两个表的
HomeTeam字段字符集排序规则不一致,存在大小写敏感的差异,同个队名因为大小写规则不统一无法匹配,同样会导致去重失效
快速修正方案
- 执行完INSERT语句后,手动调用连接对象的提交方法:
db.commit();如果不需要手动控制事务,也可以在初始化mysql.connector连接时加上参数autocommit=True - 修改INSERT语句,显式写出需要插入的字段列表,彻底避免列顺序错位的问题,同时把子查询里的字段列表简化为
SELECT 1(写法更通用,不影响执行效率)INSERT INTO 11sixteen.game_results (date, HomeTeam, AwayTeam, -- 后续补充正式表所有字段名 ) SELECT date, HomeTeam, AwayTeam, -- 后续补充临时表对应同名字段 FROM 11sixteen.new_game_results t1 WHERE NOT EXISTS ( SELECT 1 FROM 11sixteen.game_results t2 WHERE t2.date = t1.date AND t2.HomeTeam = t1.HomeTeam ) - 执行完SQL后打印游标返回的影响行数:
print(my_cursor.rowcount),通过实际插入条数判断执行效果,不要仅靠固定打印的"complete"判断流程是否正常
内容的提问来源于stack exchange,提问作者Ruben Ferreira
相关产品推荐
相关产品推荐

