#!/usr/bin/env python3 # -*- coding: utf-8 -*- """M11b-2c: 测试夹具 DDL 与列契约对齐补丁(只改 tests/,不动业务代码与表定义 JSON)。 根因(实测):tests/test_m11b2_single_tx.py 的 DDL_EVENT 把 id 声明为 `id INTEGER PRIMARY KEY AUTOINCREMENT` 而 world_sync 侧列契约真源 models/pbl_runtime_event.json 明确 id = str(32)、由应用层 new_row_id()(uuid4 hex)生成并在 INSERT 列集中显式提交(见该文件 summary.comment 「id 生成方 · 单一口径,QC #4」)。写路径插入 32 位十六进制字符串到 INTEGER 主键列 => sqlite3.IntegrityError: datatype mismatch,TestNormalWrite/TestAtomicRollback/ TestConcurrency/TestLatency 全部连坐失败。属夹具建表与契约不一致,修夹具即可。 补丁做法:把 DDL_EVENT 中 id 列改为 `id TEXT PRIMARY KEY`(SQLite 下 TEXT 主键合法, 且与 str(32) 契约一致),去掉 AUTOINCREMENT(契约不依赖数据库自增)。 """ import io import os import sys TARGET = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tests", "test_m11b2_single_tx.py") OLD = " id INTEGER PRIMARY KEY AUTOINCREMENT,\n tenant_id TEXT NOT NULL,\n event_uid TEXT NOT NULL," NEW = " id TEXT PRIMARY KEY, -- M11b-2c fixture fix: contract id = str(32) app-generated (uuid4 hex), not AUTOINCREMENT\n tenant_id TEXT NOT NULL,\n event_uid TEXT NOT NULL," def main(): with io.open(TARGET, "r", encoding="utf-8") as f: src = f.read() n = src.count(OLD) if n == 0: if NEW.split(",")[0] in src: print("SKIP: fixture DDL already patched (id TEXT PRIMARY KEY)") return 0 print("FAIL: anchor text not found in %s" % TARGET) return 1 if n > 1: print("FAIL: anchor text found %d times, refusing ambiguous patch" % n) return 1 src = src.replace(OLD, NEW) with io.open(TARGET, "w", encoding="utf-8") as f: f.write(src) print("OK: patched %s (1 occurrence) -> id TEXT PRIMARY KEY" % TARGET) return 0 if __name__ == "__main__": sys.exit(main())