修复 169 源文件瞬态导致的 “File is not a zip file”
根因:源 Excel 常被打开/保存,download 在拷贝瞬间抓到 0 字节或 残缺文件,openpyxl 解析即报 “File is not a zip file”;且 runner 在 download 之后、parse 之前就无条件 save_baseline,把 size=0 的瞬态 源记成 “已处理”,污染基线。 修复: - source_watcher.download:下载后校验(非空 + ZIP 头 PK),不合法 则删除并重试(默认 3 次,间隔 3s 等待源落盘)。 - source_watcher.has_changed:源不可达时优雅跳过本轮(WARNING), 不再每轮刷 traceback(169 间歇不可达为已知问题)。 - runner.run_once:save_baseline 移到整轮(解析+写库)成功之后, 杜绝把损坏/瞬态源记为已处理。
This commit is contained in:
@@ -38,17 +38,17 @@ def setup_logging(cfg):
|
||||
|
||||
|
||||
def run_once(cfg, source_path=None, dry_run=False):
|
||||
unc = cfg["source"]["unc_path"]
|
||||
cache = cfg["source"]["local_cache_dir"]
|
||||
meta_path = os.path.join(cache, ".source_meta.json")
|
||||
|
||||
if source_path:
|
||||
local_file = source_path
|
||||
logger.info("使用本地源: %s", local_file)
|
||||
else:
|
||||
unc = cfg["source"]["unc_path"]
|
||||
cache = cfg["source"]["local_cache_dir"]
|
||||
meta_path = os.path.join(cache, ".source_meta.json")
|
||||
if not source_watcher.has_changed(unc, meta_path):
|
||||
return
|
||||
local_file = source_watcher.download(unc, cache)
|
||||
source_watcher.save_baseline(meta_path, source_watcher.get_source_meta(unc))
|
||||
|
||||
records, fields = parse_excel(local_file, cfg.get("field_map", {}))
|
||||
|
||||
@@ -64,6 +64,14 @@ def run_once(cfg, source_path=None, dry_run=False):
|
||||
|
||||
sync_all(cfg, records, fields)
|
||||
|
||||
# 仅整轮(解析 + 写库)成功后才落基线,
|
||||
# 避免把瞬态/损坏源记为“已处理”(曾导致基线被记成 size=0)。
|
||||
if not source_path:
|
||||
try:
|
||||
source_watcher.save_baseline(meta_path, source_watcher.get_source_meta(unc))
|
||||
except OSError as e:
|
||||
logger.warning("保存基线失败(不影响本次同步): %s", e)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="采购执行情况即时数据 同步服务")
|
||||
|
||||
Reference in New Issue
Block a user