- db_migrate.py: create_all 后调用 run_structural() → 复用 treasury_migrate(幂等、特权连接) - treasury_migrate.py: 换特权连接(CMA_MIGRATE_DB_USER 或本机 root socket,禁 cma_api);up() 增 grant_app_account()(cma_api 对 6 张 treasury 表 DML,双 host) - 效果:deploy 链由特权账号一次性完成 建表+补列(cash_plans 4列/1索引)+种子(8规则/6限额)+授权 Ref: 0-P0-project-20260915-cma-treasury-stage1
This commit is contained in:
@@ -226,6 +226,25 @@ def cmd_check(args, engine, conn_desc) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def run_structural() -> dict:
|
||||
"""结构增量(补列/索引/种子/授权)——create_all 覆盖不到。
|
||||
复用 `treasury_migrate.py --apply`(幂等;其自身走特权连接)。失败不中断部署,只告警+留痕。"""
|
||||
script = os.path.join(HERE, "treasury_migrate.py")
|
||||
if not os.path.exists(script):
|
||||
return {"status": "skipped", "reason": "treasury_migrate.py 不存在"}
|
||||
try:
|
||||
proc = subprocess.run([sys.executable, script, "--apply"],
|
||||
capture_output=True, text=True, timeout=300)
|
||||
except Exception as exc:
|
||||
return {"status": "error", "reason": f"{type(exc).__name__}: {exc}"}
|
||||
return {
|
||||
"status": "ok" if proc.returncode == 0 else "failed",
|
||||
"rc": proc.returncode,
|
||||
"stdout_tail": (proc.stdout or "").strip()[-600:],
|
||||
"stderr_tail": (proc.stderr or "").strip()[-400:],
|
||||
}
|
||||
|
||||
|
||||
def cmd_apply(args, engine, conn_desc) -> int:
|
||||
Base = _import_models()
|
||||
before_missing, before_cols = schema_diff(engine)
|
||||
@@ -250,6 +269,8 @@ def cmd_apply(args, engine, conn_desc) -> int:
|
||||
try:
|
||||
if before_missing:
|
||||
Base.metadata.create_all(bind=engine) # checkfirst=True → 已存在的表零动作
|
||||
# 结构增量(补列/索引/种子/授权):create_all 不补列 → 复用 treasury_migrate(幂等,特权连接)
|
||||
structural = run_structural()
|
||||
after_missing, after_cols = schema_diff(engine)
|
||||
created = [t for t in before_missing if t not in after_missing]
|
||||
payload.update(
|
||||
@@ -258,6 +279,7 @@ def cmd_apply(args, engine, conn_desc) -> int:
|
||||
created_tables=created,
|
||||
created_new=len(created),
|
||||
missing_tables_after=after_missing,
|
||||
structural=structural,
|
||||
)
|
||||
path = write_journal(payload)
|
||||
except Exception as exc: # DDL 无事务:失败时记录已建对象,供 --rollback 恢复
|
||||
@@ -283,8 +305,9 @@ def cmd_apply(args, engine, conn_desc) -> int:
|
||||
print(f"[apply] 新建 {payload['created_new']} 张表: {created if created else '(无 → 幂等空跑)'}")
|
||||
print(f"[apply] 迁移后缺失表 {len(payload['missing_tables_after'])} 张: "
|
||||
f"{payload['missing_tables_after'] if payload['missing_tables_after'] else '(无)'}")
|
||||
print(f"[apply] 结构增量(treasury_migrate) status={structural.get('status')} rc={structural.get('rc')}")
|
||||
if after_cols:
|
||||
print(f"[apply] ⚠️ 列级差异(create_all 不补列,需独立 ALTER): {after_cols}")
|
||||
print(f"[apply] ⚠️ 列级差异仍存(结构步未覆盖): {after_cols}")
|
||||
print(f"[apply] journal: {path}")
|
||||
if not ok:
|
||||
print("[FAIL] 迁移后自检不一致(仍有缺失表)→ 部署链应中止")
|
||||
|
||||
Reference in New Issue
Block a user