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

如何修改Python代码实现CSV导入关系数据库时避免插入重复条目

问题核心原因
  • 建表未给shows.title、genres.genre添加唯一约束,INSERT OR IGNORE仅在触发唯一键冲突时才会跳过插入,无约束场景下重复数据会正常写入
  • shows表无去重插入逻辑,每读取一行CSV就直接插入,同名称影视会生成多条重复记录
  • 多类型影视的关联表插入写在类型遍历循环外,仅会保存最后一个分类的映射关系
  • INSERT OR IGNORE跳过插入时,返回值不是对应已存在记录的ID,需额外查询获取正确主键
修正后完整代码
import csv
from cs50 import SQL

# 初始化数据库
open("shows.db", "w").close()
db = SQL("sqlite:///shows.db")

# 建表新增唯一约束,主键指定自增
db.execute("""
CREATE TABLE shows (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT UNIQUE NOT NULL
)
""")
db.execute("""
CREATE TABLE genres (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    genre TEXT UNIQUE NOT NULL
)
""")
db.execute("""
CREATE TABLE shows_genres (
    show_id INTEGER NOT NULL,
    genre_id INTEGER NOT NULL,
    FOREIGN KEY(show_id) REFERENCES shows(id),
    FOREIGN KEY(genre_id) REFERENCES genres(id),
    PRIMARY KEY(show_id, genre_id)
)
""")

# 可选:如果需要实现影视名称别名映射(比如Games of Thrones显示为GoT),可以加这个字典
title_alias = {
    "GAMES OF THRONES": "GoT"
}

with open("Favorite TV Shows - Form Responses 1.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        # 统一标题大小写
        raw_title = row["title"].strip().upper()
        # 应用别名(不需要可以直接用raw_title插入)
        show_title = title_alias.get(raw_title, raw_title)
        
        # 插入或忽略影视,之后查询对应ID
        db.execute("INSERT OR IGNORE INTO shows (title) VALUES (?)", show_title)
        show_id = db.execute("SELECT id FROM shows WHERE title = ?", show_title)[0]["id"]
        
        # 遍历处理每个分类
        for genre in row["genres"].split(", "):
            # 插入或忽略分类,之后查询对应ID
            db.execute("INSERT OR IGNORE INTO genres (genre) VALUES (?)", genre)
            genre_id = db.execute("SELECT id FROM genres WHERE genre = ?", genre)[0]["id"]
            # 插入关联关系,联合主键避免重复映射
            db.execute("INSERT OR IGNORE INTO shows_genres (show_id, genre_id) VALUES (?, ?)", show_id, genre_id)
关键修改说明
  • 表结构优化:给shows.title、genres.genre加UNIQUE约束,给shows_genres加联合主键,从存储层避免重复数据
  • 去重逻辑完善:字典表都用INSERT OR IGNORE插入,插入后通过字段值查询主键ID,保证ID获取正确
  • 关联逻辑修正:关联表插入移到分类遍历循环内,保证多类型影视每个分类都有正确映射
  • 可选别名配置:如果需要将长名称影视替换为简写,直接修改title_alias字典即可匹配期望输出的名称格式

内容的提问来源于stack exchange,提问作者Minh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:57:04