导入PostgreSQL完成后如何将.csv文件从原文件夹转移至已处理文件夹
需求可行性答复
该需求完全可以实现,以下是两种生产环境常用的落地方案:
方案1:定时任务触发(适配你当前10分钟推送的频率,实现成本最低)
- 编写对应脚本,核心执行逻辑按以下顺序编排:
- 遍历待处理CSV目录下所有
.csv后缀文件,可按文件生成时间排序保证导入顺序符合要求 - 先校验文件状态:确认文件大小不为0、没有被其他进程占用(避免导入还没传输完成的半份文件)
- 执行PostgreSQL导入逻辑,建议用事务包裹导入操作,导入失败自动回滚,不会污染原有数据
- 确认导入返回成功后,将对应CSV文件移动到已处理目录,可在文件名前加导入时间戳后缀避免重名冲突
- 遍历待处理CSV目录下所有
- 脚本编写完成后,Linux系统可配置
cron定时任务、Windows系统可配置任务计划程序,设置每10分钟执行一次即可,和你的文件推送频率完全适配。
参考Shell脚本示例(Linux环境)
#!/bin/bash # 自定义配置项 WATCH_DIR="/opt/csv/untreated" PROCESSED_DIR="/opt/csv/processed" PG_HOST="127.0.0.1" PG_PORT="5432" PG_USER="postgres" PG_DB="business_db" PG_TARGET_TABLE="data_table" # 遍历所有待处理CSV for csv_file in "$WATCH_DIR"/*.csv; do [ -e "$csv_file" ] || continue # 校验文件是否被占用 if ! lsof "$csv_file" > /dev/null 2>&1; then # 事务包裹导入操作 import_result=$(psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -q -t << EOF BEGIN; COPY $PG_TARGET_TABLE FROM '$csv_file' DELIMITER ',' CSV HEADER; SELECT 1; COMMIT; EOF ) # 导入成功则移动文件 if [[ $import_result == *"1"* ]]; then mv "$csv_file" "$PROCESSED_DIR/$(date +%Y%m%d%H%M%S)_$(basename "$csv_file")" fi fi done
方案2:文件系统监听触发(实时性更高,不需要等待定时周期)
如果需要新文件上传后立刻导入,不需要等10分钟的定时周期,可以用文件系统事件监听实现:
- Linux环境可以用
inotifywait工具监听待处理目录的close_write事件,检测到新文件写入完成后自动触发导入、移动逻辑 - Windows环境可以通过.NET的FileSystemWatcher接口实现同款监听逻辑,核心处理逻辑和上述脚本一致。
注意事项
- 导入失败的文件不会被移动,下一次执行逻辑时会自动重试,可额外增加失败次数统计和告警逻辑,连续失败多次后推送通知排查问题
- 已处理目录可以配置定期清理规则,比如自动删除30天以上的历史文件,避免磁盘空间被占满
内容的提问来源于stack exchange,提问作者Ana Rita Ferreira
相关产品推荐
相关产品推荐

