Ruby使用CSV导入数据前如何检测表头是否存在 避免重复写入
问题原因
你当前代码重复写入表头的核心原因是:
- 每次调用
save_job_to_csv时,都是以追加模式("a")重新打开CSV文件 - 追加模式下,
CSV.open初始化的csv对象不会主动读取文件已有的内容,所以csv.blank?的判断每次都会返回true,导致每次调用都会写入表头
可行解决方案
方案1:修改表头判断逻辑,判断文件本身是否已存在内容
不用判断csv对象是否为空,改为直接判断目标文件是否存在且非空,调整save_job_to_csv方法即可:
def save_job_to_csv(job_data) filepath = "tmp/jobs/jobs.csv" # 先判断文件是否存在且大小大于0 file_existed = File.exist?(filepath) && File.size(filepath) > 0 CSV.open(filepath, "a") do |csv| # 只有文件不存在/为空的时候才写表头 csv << CompanyJob.attribute_names unless file_existed csv << job_data.attributes.values end end
提示:这种场景下不需要加:headers => true参数,该参数是用于读取CSV时自动解析表头用的,写入CSV时不需要配置
方案2:更高效的批量写入(推荐)
如果你的job_datas是一次性加载到内存的,不需要逐次追加写入,直接一次性打开CSV文件写入所有内容,性能更高也不会出现表头重复问题:
# 把循环逻辑放到CSV.open块内部,不需要反复打开关闭文件 filepath = "tmp/jobs/jobs.csv" CSV.open(filepath, "w") do |csv| # 先一次性写入表头 csv << CompanyJob.attribute_names job_datas.each do |job_data| @company_job = # 你的job数据转换逻辑 csv << @company_job.attributes.values end end
这种方案省去了反复IO打开关闭的开销,适合批量处理数据的场景。
内容的提问来源于stack exchange,提问作者Dung Nguyen
相关产品推荐
相关产品推荐

