如何通过Python防止SQL表中重复数据插入?
防止SQL表重复插入数据的实用方案(针对你的Python代码场景)
看起来你想避免往bp表中插入重复的systolic值,这里有几个从基础到进阶的解决思路,结合你的代码逐一说明:
1. 数据库层面加唯一约束(最可靠的底层保障)
这是最推荐的方案,因为不管程序逻辑有没有漏洞,数据库本身会拦截重复数据。你需要给systolic字段添加UNIQUE约束:
ALTER TABLE bp ADD CONSTRAINT unique_systolic UNIQUE (systolic);
之后在Python代码里,你可以捕获数据库抛出的重复键异常,做友好处理:
input_bp_systolic = input("please enter systolic value") input_bp_diastolic = input("please enter diastolic value") input_bp_description = input("please enter category") sql_scripts = "INSERT INTO bp(systolic, diastolic, description) values(?,?,?)" data = [input_bp_systolic, input_bp_diastolic, input_bp_description ] try: cur.execute(sql_scripts, data) con.commit() print("数据插入成功") except con.IntegrityError: print(f"已存在systolic值为{input_bp_systolic}的记录,无法重复插入")
2. 使用SQL的"插入时冲突处理"语句(高效且安全)
如果你的数据库支持(比如MySQL的ON DUPLICATE KEY UPDATE,PostgreSQL的ON CONFLICT),可以直接用一条SQL语句完成"检查+插入",避免先查询再插入的额外开销:
MySQL示例:
sql_scripts = """ INSERT INTO bp(systolic, diastolic, description) VALUES(?,?,?) ON DUPLICATE KEY UPDATE diastolic = VALUES(diastolic), description = VALUES(description); """ # 这条语句会在systolic重复时,更新现有记录的diastolic和description;若想直接忽略重复,可根据数据库特性调整(比如用IGNORE) cur.execute(sql_scripts, data) con.commit()
PostgreSQL示例:
sql_scripts = """ INSERT INTO bp(systolic, diastolic, description) VALUES(?,?,?) ON CONFLICT (systolic) DO NOTHING; """ # DO NOTHING表示遇到重复时直接跳过插入,若想更新现有记录,可换成DO UPDATE SET ... cur.execute(sql_scripts, data) con.commit()
3. Python层面先查询再插入(适合简单低并发场景)
这就是你代码里设想的思路,先查询数据库中是否存在该systolic值,不存在再插入。但要注意高并发场景下可能出现竞态条件(比如两个请求同时查询都没找到,然后都插入),所以只适合单线程或低并发的小项目:
input_bp_systolic = input("please enter systolic value") # 先查询是否存在目标systolic值 check_sql = "SELECT 1 FROM bp WHERE systolic = ?" cur.execute(check_sql, (input_bp_systolic,)) exists = cur.fetchone() if not exists: input_bp_diastolic = input("please enter diastolic value") input_bp_description = input("please enter category") insert_sql = "INSERT INTO bp(systolic, diastolic, description) values(?,?,?)" data = [input_bp_systolic, input_bp_diastolic, input_bp_description ] cur.execute(insert_sql, data) con.commit() print("数据插入成功") else: print(f"systolic值{input_bp_systolic}已存在,无需重复插入")
总结一下:优先选择数据库唯一约束+异常处理,或者SQL冲突语句,这两种方案更安全高效;Python先查后插仅适合简单低并发场景。
内容的提问来源于stack exchange,提问作者H kan
相关产品推荐
相关产品推荐

