run_sop_visible_deploy.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/env python3
  2. """在测试/本地库执行 SOP 精简展示部署 SQL。"""
  3. from __future__ import annotations
  4. import re
  5. import sys
  6. from pathlib import Path
  7. ROOT = Path(__file__).resolve().parents[2]
  8. sys.path.insert(0, str(ROOT / "backend"))
  9. from sqlalchemy import create_engine, text # noqa: E402
  10. try:
  11. from app.core.config import settings # noqa: E402
  12. except Exception as exc: # pragma: no cover
  13. raise SystemExit(f"无法加载 backend 配置: {exc}") from exc
  14. SQL_DIR = ROOT / "docs" / "sql"
  15. SOP_CODES = [
  16. "SOP-CC-001-E01-01",
  17. "SOP-CC-002-E01-01",
  18. "SOP-CC-003-E01-01",
  19. "SOP-CC-006-E01-01",
  20. "SOP-SC-003-E01-01",
  21. "SOP-SC-004-E01-01",
  22. "SOP-SC-005-E01-01",
  23. "SOP-SC-006-E01-01",
  24. "SOP-SC-007-E01-01",
  25. "SOP-SC-008-E01-01",
  26. "SOP-SC-009-E01-01",
  27. "SOP-SC-010-E01-01",
  28. "SOP-SC-011-E01-01",
  29. "SOP-SC-012-E01-01",
  30. "SOP-SC-013-E01-01",
  31. "SOP-SC-014-E01-01",
  32. ]
  33. UPDATE_STMT_RE = re.compile(r"\bUPDATE\b.+?;", re.IGNORECASE | re.DOTALL)
  34. def _strip_sql_comments(sql: str) -> str:
  35. lines = []
  36. for line in sql.splitlines():
  37. if line.strip().startswith("--"):
  38. continue
  39. lines.append(line)
  40. return "\n".join(lines)
  41. def _run_seed_file(conn, path: Path) -> int:
  42. sql = path.read_text(encoding="utf-8").strip()
  43. if not sql:
  44. return 0
  45. result = conn.execute(text(sql))
  46. return result.rowcount or 0
  47. def _run_sync_file(conn, path: Path) -> int:
  48. raw = _strip_sql_comments(path.read_text(encoding="utf-8"))
  49. total = 0
  50. for stmt in UPDATE_STMT_RE.findall(raw):
  51. result = conn.execute(text(stmt.strip()))
  52. total += result.rowcount or 0
  53. return total
  54. def main() -> None:
  55. engine = create_engine(settings.DATABASE_URL)
  56. total = 0
  57. with engine.begin() as conn:
  58. for code in SOP_CODES:
  59. short = code.replace("SOP-", "").replace("-E01-01", "").lower()
  60. seed = SQL_DIR / f"2026-08-25-seed-sop-{short}-content.sql"
  61. sync = SQL_DIR / f"2026-08-25-sync-sop-{short}-content-to-routes-tasks.sql"
  62. n1 = _run_seed_file(conn, seed)
  63. n2 = _run_sync_file(conn, sync) if sync.exists() else 0
  64. total += n1 + n2
  65. print(f"{code}: process={n1}, sync={n2}")
  66. print(f"done, affected rows (approx): {total}")
  67. if __name__ == "__main__":
  68. main()