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

使用Python拼接SQL文件 去重保留最新文件解决UNIQUE约束报错

问题场景
  • 目录下存储230个左右.txt格式的SQL文件,每个文件包含约1000行INSERT INTO语句,用于填充SQLite数据库
  • 需求是合并所有文件为单个文本文件实现一次性加载,因数据库设置了UNIQUE约束,重复ID的记录需保留文件创建时间最新的版本,最终去重后约保留200个文件的内容,所有INSERT语句按顺序排列
  • 原有pandas脚本去重逻辑失效,导入数据库时仍触发UNIQUE约束报错
原有脚本核心问题
  • 去重操作结果未赋值:groupby+apply的去重逻辑仅生成了临时新对象,没有将结果回写到df变量,后续所有操作仍基于未去重的原始DataFrame执行
  • 排序结果未被使用:排序后的对象赋值给了独立变量sort,后续拼接内容时完全没有调用该变量
  • 最新文件判定逻辑错误:glob遍历文件的顺序不遵循文件名中的时间戳排序,直接取分组内iloc[[-1]]无法保证拿到的是时间最新的文件
  • 语句拼接分隔符错误:用空格作为SQL语句的拼接分隔符,容易出现前后语句粘连的语法问题
修正后的pandas实现代码
from pathlib import Path
import pandas as pd

path = "你的SQL文件目录路径"
output_path = "合并后输出文件路径"

df = pd.DataFrame(columns=['truncated_name', 'timestamp', 'content'])
for p in Path(path).glob('**/*.txt'):
    filename = p.name
    # 拆分截断文件名、12位时间戳(例:202206141707)、文件内容
    truncated_name = filename[:-16]
    ts = int(filename[-16:-4])  # 时间戳转整数方便排序
    content = p.read_text(encoding='utf-8')
    df.loc[len(df)] = [truncated_name, ts, content]

# 先按时间戳升序排序,再按截断文件名去重,保留最后一条(即时间最新的记录)
df = df.sort_values(by="timestamp", ascending=True).drop_duplicates(subset="truncated_name", keep="last")
# 按截断文件名排序保证语句顺序
df = df.sort_values(by="truncated_name", ascending=False)
# 用换行作为分隔符拼接所有SQL内容,避免语句粘连
output_text = df['content'].str.cat(sep='\n')

with open(output_path, 'w', encoding='utf-8') as f:
    f.write(output_text)
无pandas轻量实现方案

文件总量仅230个,无需依赖pandas,用Python标准库即可实现,逻辑更直观不易出错:

from pathlib import Path

path = "你的SQL文件目录路径"
output_path = "合并后输出文件路径"

file_map = {}
for p in Path(path).glob('**/*.txt'):
    filename = p.name
    truncated_name = filename[:-16]
    ts = int(filename[-16:-4])
    content = p.read_text(encoding='utf-8')
    # 仅当当前key不存在、或当前文件时间戳更新时,才存入字典
    if truncated_name not in file_map or ts > file_map[truncated_name][0]:
        file_map[truncated_name] = (ts, content)

# 按截断文件名倒序排序后拼接内容
sorted_contents = [v[1] for k, v in sorted(file_map.items(), key=lambda x: x[0], reverse=True)]
output_text = '\n'.join(sorted_contents)

with open(output_path, 'w', encoding='utf-8') as f:
    f.write(output_text)

额外提示:如果单文件内部也存在同ID重复的INSERT语句,上述文件级去重无法覆盖该场景,可在导入SQLite时直接使用INSERT OR REPLACE语法,数据库会自动按UNIQUE约束覆盖旧记录,无需提前做行级去重,容错性更高。

内容的提问来源于stack exchange,提问作者C. Crt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:15:51