#!/usr/bin/env python3 """Schema 一致性检查 — 部署门禁 检查 ORM model 与数据库表结构是否一致,输出差异并给出修复建议。 运行: python3 scripts/schema_check.py """ import sys, os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from sqlalchemy import inspect, text from app.database import get_engine import app.models def main(): engine = get_engine() insp = inspect(engine) db_tables = set(insp.get_table_names()) model_tables = set(app.models.Base.metadata.tables.keys()) print("===== CMA Schema 一致性检查 =====") print(f"数据库表: {len(db_tables)} | ORM模型表: {len(model_tables)}") print() issues = 0 # 1. 表缺失 missing_tables = model_tables - db_tables if missing_tables: issues += len(missing_tables) print(f"❌ ORM有但数据库缺失的表: {missing_tables}") print(" 修复: 运行 Base.metadata.create_all() 或手动建表") else: print("✅ 表结构齐全") # 2. 字段差异 for tbl in sorted(model_tables & db_tables): model_cols = set(app.models.Base.metadata.tables[tbl].columns.keys()) db_cols = set(c["name"] for c in insp.get_columns(tbl)) missing = model_cols - db_cols extra = db_cols - model_cols if missing: issues += len(missing) print(f"❌ [{tbl}] 数据库缺ORM字段: {missing}") print(f" 修复: ALTER TABLE {tbl} ADD COLUMN ...") if extra: # 数据库有但ORM没有的字段 — 检查是否NOT NULL且ORM创建时不填 print(f"⚠️ [{tbl}] ORM未定义但数据库有: {extra}") # 3. 关键表字段检查(只报真实结构差异:ORM有DB缺,或DB有ORM缺) critical = ["kpi_definitions", "kpi_values", "strategic_maps", "budget_plans", "action_plans"] for tbl in critical: if tbl not in db_tables: continue model_cols = set(app.models.Base.metadata.tables[tbl].columns.keys()) db_cols = set(c["name"] for c in insp.get_columns(tbl)) missing = model_cols - db_cols extra = db_cols - model_cols if missing: issues += len(missing) print(f"❌ [{tbl}] 数据库缺ORM字段: {missing}") print(f" 修复: ALTER TABLE {tbl} ADD COLUMN ...") if extra: # DB有ORM无 → 可能影响ORM写入/读取,提示但不阻塞 print(f"⚠️ [{tbl}] ORM未定义但数据库有: {extra}") print() if issues: print(f"🚨 发现 {issues} 处差异,需处理后再部署") sys.exit(1) else: print("✅ Schema 一致,无阻塞问题") sys.exit(0) if __name__ == "__main__": main()