You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已设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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 02:32:39