使用pymysql执行INSERT IGNORE时rowcount始终返回1,如何判断记录是否插入?
解决pymysql中INSERT IGNORE无法判断是否插入/更新的问题
你这个问题的核心原因是:INSERT ... SELECT语句里,cursor.execute()返回的是SELECT查询返回的行数,而不是实际插入到Table表的行数。另外如果Table的key字段没设置唯一约束(UNIQUE或PRIMARY KEY),INSERT IGNORE根本不会触发忽略逻辑,重复数据也会被插入,自然rowcount始终是1。
下面是几种可行的解决方法:
方法1:先确保目标表有唯一约束
先检查Table表的key字段是否设置了唯一约束,这是INSERT IGNORE生效的前提。如果没有,执行以下SQL添加约束:
ALTER TABLE `Table` ADD UNIQUE KEY `unique_key` (`key`);
方法2:改用INSERT ... ON DUPLICATE KEY UPDATE区分插入/更新
用这个语法替代INSERT IGNORE,MySQL会在遇到唯一键冲突时自动执行更新,此时cursor.rowcount会返回明确的数值:
- 返回1:成功插入新记录
- 返回2:更新了已存在的记录
- 返回0:SELECT语句没有返回符合条件的行,无操作
示例代码:
import pymysql db = pymysql.connect(host='127.0.0.1',user='USERNAME',password='PASSWORD',database='DATABASE') cursor = db.cursor() sql = """ INSERT INTO `Table` (key, via) SELECT temp.`id`, 'Via_Bot' FROM (SELECT %s AS id) temp LEFT JOIN `Other_Table` ON `Other_Table`.id = temp.id WHERE `Other_Table`.id IS NULL ON DUPLICATE KEY UPDATE via = 'Via_Bot'; -- 这里可以设置实际要更新的字段值 """ key_id = 'ab12cd' rows = cursor.execute(sql, (key_id,)) if rows == 1: print("新记录已插入") elif rows == 2: print("已有记录被更新") else: print("无记录被插入或更新") db.commit()
方法3:插入后直接查询验证
如果不想修改原有SQL逻辑,可以在执行INSERT后,直接查询Table表是否存在该记录:
import pymysql db = pymysql.connect(host='127.0.0.1',user='USERNAME',password='PASSWORD',database='DATABASE') cursor = db.cursor() # 原有插入语句 sql = "INSERT IGNORE INTO `Table` (key, via) SELECT temp.`id`, 'Via_Bot' FROM (SELECT %s AS id) temp LEFT JOIN `Other_Table` ON `Other_Table`.id = temp.id WHERE `Other_Table`.id IS NULL;" key_id = 'ab12cd' cursor.execute(sql, (key_id,)) # 查询验证 cursor.execute("SELECT 1 FROM `Table` WHERE `key` = %s", (key_id,)) if cursor.fetchone(): print("记录已存在或已成功插入") else: print("无记录被插入") db.commit()
方法4:利用自增主键的lastrowid判断(限有自增主键的表)
如果Table表有自增主键字段,插入新记录时cursor.lastrowid会返回新生成的主键值;没有插入时则返回0或None。可以结合这个值判断:
import pymysql db = pymysql.connect(host='127.0.0.1',user='USERNAME',password='PASSWORD',database='DATABASE') cursor = db.cursor() sql = "INSERT IGNORE INTO `Table` (key, via) SELECT temp.`id`, 'Via_Bot' FROM (SELECT %s AS id) temp LEFT JOIN `Other_Table` ON `Other_Table`.id = temp.id WHERE `Other_Table`.id IS NULL;" key_id = 'ab12cd' cursor.execute(sql, (key_id,)) if cursor.lastrowid != 0: print("新记录已插入") else: # 进一步区分是冲突被忽略还是无符合条件的行 cursor.execute("SELECT 1 FROM `Table` WHERE `key` = %s", (key_id,)) if cursor.fetchone(): print("记录已存在,未插入新数据") else: print("无符合条件的记录被插入") db.commit()
内容的提问来源于stack exchange,提问作者Bijan
相关产品推荐
相关产品推荐

