已设FOREIGN KEY约束仍出现重复记录,如何解决SQLite数据重复问题?
解决SQLite商品管理程序重复插入问题
1. 核心问题:缺少唯一约束
prices表的外键仅保证product_id关联的商品存在于products表,但不限制同一个product_id重复插入。INSERT OR IGNORE生效的前提是表存在对应的UNIQUE约束,否则无法识别"重复"。
2. 修复步骤
(1)为prices表添加唯一约束
如果表尚未创建,在建表语句中直接加入UNIQUE约束:
import sqlite3 conn = sqlite3.connect('product_manage.db') cursor = conn.cursor() cursor.execute('PRAGMA foreign_keys = ON;') # 必须开启外键功能,SQLite默认关闭 # 创建带唯一约束的prices表 cursor.execute(''' CREATE TABLE IF NOT EXISTS prices ( price_id INTEGER PRIMARY KEY AUTOINCREMENT, product_id INTEGER NOT NULL, price REAL NOT NULL, FOREIGN KEY (product_id) REFERENCES products(product_id), UNIQUE(product_id) # 关键:确保同一个商品ID只存一条价格记录 ) ''') conn.commit()
如果表已存在,可通过ALTER语句添加约束(需SQLite 3.35.0及以上版本):
cursor.execute('ALTER TABLE prices ADD CONSTRAINT unique_product UNIQUE(product_id);') conn.commit()
(2)简化插入逻辑,用INSERT OR IGNORE替代行计数
行计数判断存在竞态风险(两次操作之间可能有其他插入),直接用原子性的INSERT OR IGNORE更可靠:
def add_price(product_id, price): cursor.execute(''' INSERT OR IGNORE INTO prices (product_id, price) VALUES (?, ?) ''', (product_id, price)) conn.commit()
(3)清理已有重复数据
如果数据库中已经存在重复条目,先清理再重新维护:
# 保留每个product_id的第一条记录,删除其余重复项 cursor.execute(''' DELETE FROM prices WHERE price_id NOT IN ( SELECT MIN(price_id) FROM prices GROUP BY product_id ) ''') conn.commit()
3. 验证修复
运行程序后插入相同product_id的价格,查询prices表:
cursor.execute('SELECT * FROM prices;') print(cursor.fetchall())
此时同一product_id只会保留一条记录。
内容的提问来源于stack exchange,提问作者JuicyTendies
相关产品推荐
相关产品推荐

