Files

76 lines
3.0 KiB
Python

"""迁移脚本:更新现有战略地图KPI codes + 关联所有活跃KPI到地图"""
from app.database import get_engine
from sqlalchemy import text
import json
def migrate():
e = get_engine()
with e.begin() as c:
# 1. 更新现有地图的dimensions → 使用真实KPI codes
maps = c.execute(text('SELECT id, dimensions FROM strategic_maps')).fetchall()
for mid, dims_json in maps:
if not dims_json:
continue
dims = json.loads(dims_json) if isinstance(dims_json, str) else dims_json
# 定义层→节点名→真实KPI code的映射
name_to_kpi = {
# 财务层
"营收目标": ["F_REVENUE"],
"净利润率": ["F_NET_PROFIT"],
"现金流": ["F_OP_CFLOW"],
# 客户层
"客户满意度": ["C_SATISFACTION"],
"市场份额": ["C_MARKET_SHARE"],
"客户保留率": ["C_RETENTION_RATE"],
# 流程层
"运营效率": ["P_DELIVERY"],
"质量合格率": ["P_PASS_RATE"],
# 学习层
"关键岗位胜任度": ["L_COMPETENCY"],
"培训完成率": ["L_TRAINING"],
}
updated = False
for dim in dims:
for obj in dim.get("objectives", []):
name = obj.get("name", "")
if name in name_to_kpi:
real_kpis = name_to_kpi[name]
if obj.get("kpis") != real_kpis:
obj["kpis"] = real_kpis
updated = True
if updated:
c.execute(
text("UPDATE strategic_maps SET dimensions = :dims WHERE id = :mid"),
{"dims": json.dumps(dims, ensure_ascii=False), "mid": mid},
)
print(f"✅ 地图 {mid}: dimensions KPI codes 已更新")
# 2. 将所有活跃KPI的map_id更新为1
result = c.execute(
text("UPDATE kpi_definitions SET map_id = 1 WHERE status = 'active' AND (map_id IS NULL OR map_id != 1)")
)
affected = result.rowcount
print(f"✅ 已更新 {affected} 个活跃KPI的 map_id → 1")
# 3. 验证
total = c.execute(text("SELECT COUNT(*) FROM kpi_definitions WHERE status='active' AND map_id = 1")).scalar()
print(f"📊 活跃KPI关联到地图1的数量: {total}")
kpis_with_data = c.execute(text("""
SELECT k.kpi_code, k.kpi_name
FROM kpi_definitions k
WHERE EXISTS (
SELECT 1 FROM kpi_values v WHERE v.kpi_id = k.id
) AND k.map_id = 1
ORDER BY k.kpi_code
""")).fetchall()
print(f"📊 有历史数据的KPI ({len(kpis_with_data)}个):")
for r in kpis_with_data:
print(f" {r.kpi_code} - {r.kpi_name}")
if __name__ == "__main__":
migrate()