使用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
相关产品推荐
相关产品推荐

