docs: document the schema mode and the expand-contract promise

README 新增「遥测表 schema 与升级纪律」: 库对下游库只发探测/INSERT/建表
三类语句、PGW_TELEMETRY_SCHEMA_MODE 三态与两端不对称缺省的理由、
telemetry_schema_sql 用法,以及五条 Expand/Contract 承诺。CHANGELOG 未发布段
把三处破坏性变更放在最前。ARCHITECTURE 新增 D15 并在 §7.8/§9 记下 schema
单一事实源与无冲突目标写入。

新增集成用例把 telemetry_schema_sql("postgres") 的输出在空临时 schema 里执行
两遍: 断言物理列 == COLUMNS ∪ {created_at},且第二遍不报错(补列语句的
IF NOT EXISTS 幂等性)。去掉 IF NOT EXISTS 该用例即红。
This commit is contained in:
2026-08-19 13:03:45 -04:00
parent 483683b834
commit ba4a138692
4 changed files with 168 additions and 3 deletions
@@ -21,6 +21,7 @@ import pytest
from dotenv import dotenv_values
from polygateway.telemetry.postgres import PostgresRecorder
from polygateway.telemetry.schema import COLUMNS, telemetry_schema_sql
_EXPECTED_COLUMNS = [
"call_id",
@@ -137,6 +138,17 @@ async def _fetch(dsn: str, sql: str, *args):
await conn.close()
async def _execute_script(dsn: str, sql: str) -> None:
"""整段执行多语句脚本(不带参数,走简单查询协议)——模拟下游把脚本贴进 psql。"""
import asyncpg
conn = await asyncpg.connect(dsn, timeout=10)
try:
await conn.execute(sql)
finally:
await conn.close()
_LEGACY_DDL = """
CREATE TABLE {schema}.llm_calls (
call_id TEXT PRIMARY KEY,
@@ -865,3 +877,39 @@ class TestManualSchemaModeAcceptance:
assert rows[1]["cost"] == 2.5
finally:
await recorder.aclose()
_PHYSICAL_COLUMNS_SQL = (
"SELECT column_name FROM information_schema.columns "
"WHERE table_schema = $1 AND table_name = 'llm_calls' ORDER BY ordinal_position"
)
class TestPublishedSchemaScript:
"""issue #13: README 叫下游执行的那份脚本,在真实实例上必须建得出、且可重复执行。
这份脚本是 `telemetry_schema_sql("postgres")` 的输出,manual 档下游拿它建表,
库随后靠列探测决定写哪些列——脚本与 `COLUMNS` 一旦漂移,表现是"照文档建完表,
库仍报缺列"。人工核对不构成回归保护: 改一次 README 或 DDL 就会悄悄失去它。
"""
async def test_script_builds_the_full_table_and_is_rerunnable(self, fresh_schema):
"""空 schema 里执行一遍建出全部物理列;再执行一遍不报错。
第二遍是 `ADD COLUMN IF NOT EXISTS` 的幂等性验收: 去掉 IF NOT EXISTS 后,
建表语句会被 `IF NOT EXISTS` 跳过而补列语句撞上 "column ... already exists",
整段脚本第二次执行即失败——而"可重复执行"正是这份脚本对下游的承诺。
"""
fresh_dsn, schema = fresh_schema
script = telemetry_schema_sql("postgres")
await _execute_script(fresh_dsn, script)
actual = [r["column_name"] for r in await _fetch(fresh_dsn, _PHYSICAL_COLUMNS_SQL, schema)]
# 物理列 = 24 个 INSERT 字段 + 库从不显式写的 created_at;对着库常量比,不另抄一份
assert set(actual) == set(COLUMNS) | {"created_at"}
# 列序也不许漂: 新列必须排在 created_at 之后,否则新建库与 ALTER 升级的列序分叉
assert actual == _EXPECTED_COLUMNS
await _execute_script(fresh_dsn, script) # 可重复执行: 第二遍不得抛
rerun = [r["column_name"] for r in await _fetch(fresh_dsn, _PHYSICAL_COLUMNS_SQL, schema)]
assert rerun == actual # 且第二遍没有偷偷改动表结构