- deploy.sh: 提交纪律检查(本地未提交修改→中止) + 冒烟测试(健康/登录/KPI/BOT/Schema) - .woodpecker: 加前端typecheck+后端pytest测试步骤, backend-deploy加提交纪律检查 - 新增schema_check.py: ORM与数据库表结构一致性检查 - 修复budget_plans表缺3列(source_kpi_id/source_type/calc_logic) - 附带入库: budget测试+文档
75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
#!/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()
|