rehearsal: union task_attempts schema (main old DDL + gap-3 ledger cols), relax 2 hook no-table asserts to no-rows, gateway-env fake tolerates main routing reads, extend single-writer fixture list by name (test-only inserts)

This commit is contained in:
host committed 2026-11-04 21:23:25 +00:00
1 parent f76a566aa8
commit 1eefe17474
4 files changed
+90 -3

No files matched your search

+42 -1
View File
@@ -168,11 +168,52 @@ OLD_TABLE_ALTER = (
)
def _existing_columns(conn, table):
"""已有列集合(automations.py 同款口径:SQLite 走 PRAGMA,
其它后端异常时回空集、后续 ALTER 逐条 try/except 兜底)。"""
try:
return {row[1] for row in conn.execute(
"PRAGMA table_info(%s)" % table).fetchall()}
except Exception:
return set()
def ensure_task_attempts_table(conn):
"""Create the ledger table if absent. Idempotent; does not
touch existing rows. The caller owns the commit (``record_attempt``
commits; a bare ensure inside a larger transaction does not)."""
commits; a bare ensure inside a larger transaction does not).
演练注 FLAG(合入语义取舍点,主结论见演练报告):
main 侧 init_db/worker 用 cloud.attempts.py 的旧 DDL 建同名
task_attempts 表(kind/interrupted_reason/checkpoint_round/
result_text/error_text,无 outcome 系列);本模块的 CREATE
TABLE IF NOT EXISTS 在旧表已存在时是空操作,之后按台账
列写行即报 no column named outcome。本解法把表升级为两
组列的并集:旧表先建时补台账 4 列,台账表先建时补旧 5
列(新增列一律可空/带默认值,绝不对已有行加 NOT NULL,
否则旧行会挡住 ALTER)。两边读路径均按列名取数,互不
干扰;但这只是演练期保守解法——真合前须用户定:并集表、
台账改名、或统一 schema 三选一,不可悄悄定为并集表。
"""
conn.execute(SQLITE_DDL)
existing = _existing_columns(conn, "task_attempts")
for col, ddl in (
("outcome", "TEXT"),
("is_defect", "INTEGER DEFAULT 0"),
("defect_category", "TEXT"),
("corrects_attempt_no", "INTEGER"),
("kind", "TEXT"),
("interrupted_reason", "TEXT"),
("checkpoint_round", "INTEGER"),
("result_text", "TEXT"),
("error_text", "TEXT")):
if col not in existing:
try:
conn.execute(
"ALTER TABLE task_attempts ADD COLUMN %s %s"
% (col, ddl))
except Exception:
pass
def record_attempt(conn, task_id, outcome, is_defect=False,