用 Codex 做导入预览:文件变了,就拒绝旧计划

导入预览看起来没问题,准备提交时,原文件却被另一个操作改过了。之前确认的预览,还能直接执行吗?

这次接着整批校验后再写文件的教学例子,把预览和提交拆成两次操作,中间多加一次输入对照。数据仍是自建 JSON,不是真实库存。

预览时留下什么

程序读取原文件与待导入批次,完成整批校验,再生成一份独立的计划文件,里面保存两份输入各自的 SHA-256 指纹和计算出的预览结果。

这里的“预览”会创建计划文件,但不修改库存副本。计划路径已经存在时拒绝覆盖;重新预览要换一个新文件名。

SHA-256 用于计算文件字节的摘要。同一份内容只要空格或换行发生变化,本例也会视为输入变化;它没有试图判断两份 JSON 的业务含义是否相同。Python:hashlib

提交时再读一次

提交命令重新读取两份输入,与计划中的指纹比较。任意一份不同,就拒绝旧计划并保留当前库存文件。

两份输入都相同时,程序仍会重新校验整批、计算结果,再对照计划里的预览。通过后才写入指定测试副本;写入前还会再次检查库存文件是否与刚读取的字节一致。

这些检查没有持有文件锁。检查结束到替换文件之间仍有时间间隔,不能据此声称支持并发写入。os.replace 的文档也不能替代针对实际文件系统的故障和恢复测试。Python:os.replace

可以直接交给 Codex 的任务

1
2
3
4
5
6
7
这是自建 JSON 库存导入教学项目,先在可替换的测试副本演练。
增加独立的预览计划,记录原文件和导入批次各自的指纹及预览结果。
提交前重新读取两份输入、比较指纹,并再次校验和计算结果。
输入或计划中的预览不一致就停止,保留当前库存文件。
计划文件已存在时不覆盖,用新文件名重新预览。
给出原文件变化、批次变化、输入未变三个提交场景。
保存退出码,写入后重读旧行、新行和库存 0,并说明未覆盖的范围。

下载后先跑未变化的情况

下载教学代码、样例和8项验收

解压到一个新目录,在 PowerShell 中运行。以下的 test-store.json 是明确可替换的测试副本:

1
2
3
4
5
6
7
Copy-Item fixtures/store.json test-store.json
Copy-Item fixtures/good-batch.json test-batch.json
python -B test_guarded_import.py
Get-FileHash test-store.json -Algorithm SHA256
python -B guarded_import.py preview --store test-store.json --input test-batch.json --plan test-plan.json
$LASTEXITCODE
Get-FileHash test-store.json -Algorithm SHA256

预览退出码应为 0,两次库存文件哈希相同。检查计划文件,确认预览是旧记录一行、新记录两行后,再执行:

1
2
3
4
Get-Content test-plan.json -Raw
python -B guarded_import.py commit --store test-store.json --input test-batch.json --plan test-plan.json
$LASTEXITCODE
Get-Content test-store.json -Raw

提交会替换 test-store.json。预期退出 0,重读得到 3 行,其中 NEW01 的库存为数值 0。

再故意让预览过期

用不同的副本和计划名,避免覆盖前一个场景:

1
2
3
4
5
6
7
8
Copy-Item fixtures/store.json changed-store.json
Copy-Item fixtures/good-batch.json changed-batch.json
python -B guarded_import.py preview --store changed-store.json --input changed-batch.json --plan changed-plan.json
python -c "from pathlib import Path; p=Path('changed-store.json'); p.write_bytes(p.read_bytes()+b' ')"
Get-FileHash changed-store.json -Algorithm SHA256
python -B guarded_import.py commit --store changed-store.json --input changed-batch.json --plan changed-plan.json
$LASTEXITCODE
Get-FileHash changed-store.json -Algorithm SHA256

这里仅追加一个空格,JSON 仍能解析,但字节已不同。预期得到 store_changed_after_preview,退出 2;提交前后两次哈希相同,说明保留的是变更后的当前文件,没有用旧计划覆盖它。

批次变化的场景由下载包中的验收测试覆盖,对应错误为 batch_changed_after_preview。发现变化后,先确认当前文件,再用新的计划名重新预览;不要把原文件改回旧值只为让检查通过。

原始执行结果和适用范围

2026 年 10 月 28 日,Windows / Python 3.13.5 实际完成 8 项验收和 4 个命令场景:只预览不改库存副本;原文件变化后拒绝提交并保留变更后的文件;批次变化后拒绝提交且库存不变;输入未变时提交成功,重读得到 3 行并保留 0。两次拒绝均退出 2,成功退出 0。源码与原始样例哈希未变,没有 API 调用。

本文于 2026 年 10 月 29 日整理并复核官方资料,沿用上述原始执行记录。指纹不是签名或文件锁;文件变化后又恢复为相同字节,也不会被这个对照发现。没有验证真实库存、并发、磁盘故障或断电恢复。

补充资料:JSON 解码与类型转换、unittest 断言。教学代码与文章含 AI 辅助。