baodan/api/insurance/db/migrate_014.py

144 lines
5.8 KiB
Python
Raw Normal View History

"""迁移 014: 导入 PPT 配置数据。
使用原始 SQL 而非 ORM避免模型字段与实际表结构不一致的问题
ORM 模型包含 migrate_017 才创建的 slides_config_json 字段
"""
2026-07-23 13:10:50 +08:00
import os
import json
import logging
from sqlalchemy import text
2026-07-23 13:10:50 +08:00
logger = logging.getLogger(__name__)
CONFIG_DIR = os.path.join(os.path.dirname(__file__), "..", "ppt", "config")
def _read_json_file(filepath):
try:
with open(filepath, "r", encoding="utf-8") as f:
return json.load(f)
except Exception:
return None
def _read_json_files_in_dir(dirpath):
results = []
if not os.path.isdir(dirpath):
return results
for root, _, files in os.walk(dirpath):
for fname in files:
if fname.endswith(".json"):
data = _read_json_file(os.path.join(root, fname))
if data is not None:
results.append(data)
return results
def _record_exists(db, table: str, id_col: str, id_val: str) -> bool:
"""检查记录是否存在。"""
result = db.session.execute(
text(f"SELECT 1 FROM {table} WHERE {id_col} = :id LIMIT 1"),
{"id": id_val},
)
return result.fetchone() is not None
2026-07-23 13:10:50 +08:00
def migrate():
"""迁移入口。"""
from insurance.db.compat import db
# 公司
companies_dir = os.path.join(CONFIG_DIR, "companies")
count = 0
for d in _read_json_files_in_dir(companies_dir):
if not d.get("id") or _record_exists(db, "insurance_ppt_companies", "id", d["id"]):
2026-07-23 13:10:50 +08:00
continue
db.session.execute(text(
"INSERT INTO insurance_ppt_companies "
"(id, display_name, aliases_json, tenant_id, knowledge_directories_json, "
"evidence_ranking_json, company_intro, company_highlights_json) "
"VALUES (:id, :display_name, :aliases_json, :tenant_id, :knowledge_directories_json, "
":evidence_ranking_json, :company_intro, :company_highlights_json)"
), {
"id": d["id"],
"display_name": d.get("displayName", ""),
"aliases_json": json.dumps(d.get("aliases", []), ensure_ascii=False),
"tenant_id": d.get("tenantId", "default"),
"knowledge_directories_json": json.dumps(d.get("knowledgeDirectories", []), ensure_ascii=False),
"evidence_ranking_json": json.dumps(d.get("evidenceRanking", []), ensure_ascii=False),
"company_intro": d.get("companyIntro", ""),
"company_highlights_json": json.dumps(d.get("companyHighlights", []), ensure_ascii=False),
})
2026-07-23 13:10:50 +08:00
count += 1
db.session.commit()
logger.info(f"[migrate_014] 导入 {count} 家公司")
# 产品
products_dir = os.path.join(CONFIG_DIR, "products")
count = 0
for d in _read_json_files_in_dir(products_dir):
if not d.get("id") or _record_exists(db, "insurance_ppt_products", "id", d["id"]):
2026-07-23 13:10:50 +08:00
continue
db.session.execute(text(
"INSERT INTO insurance_ppt_products "
"(id, company_id, plan_type, display_name, aliases_json, required_modules_json) "
"VALUES (:id, :company_id, :plan_type, :display_name, :aliases_json, :required_modules_json)"
), {
"id": d["id"],
"company_id": d.get("companyId", ""),
"plan_type": d.get("planType", "savings"),
"display_name": d.get("displayName", ""),
"aliases_json": json.dumps(d.get("aliases", []), ensure_ascii=False),
"required_modules_json": json.dumps(d.get("requiredModules", []), ensure_ascii=False),
})
2026-07-23 13:10:50 +08:00
count += 1
db.session.commit()
logger.info(f"[migrate_014] 导入 {count} 个产品")
# 模板(只使用 migrate_014 时已存在的列)
2026-07-23 13:10:50 +08:00
templates_dir = os.path.join(CONFIG_DIR, "templates")
count = 0
for d in _read_json_files_in_dir(templates_dir):
if not d.get("id") or _record_exists(db, "insurance_ppt_templates", "id", d["id"]):
2026-07-23 13:10:50 +08:00
continue
db.session.execute(text(
"INSERT INTO insurance_ppt_templates "
"(id, plan_type, style_preset, source_template_asset_id, clone_ready, "
"clone_renderer, required_page_types_json) "
"VALUES (:id, :plan_type, :style_preset, :source_template_asset_id, :clone_ready, "
":clone_renderer, :required_page_types_json)"
), {
"id": d["id"],
"plan_type": d.get("planType", "savings"),
"style_preset": d.get("stylePreset", "broker"),
"source_template_asset_id": d.get("sourceTemplateAssetId"),
"clone_ready": d.get("cloneReady", False),
"clone_renderer": d.get("cloneRenderer"),
"required_page_types_json": json.dumps(d.get("requiredPageTypes", []), ensure_ascii=False),
})
2026-07-23 13:10:50 +08:00
count += 1
db.session.commit()
logger.info(f"[migrate_014] 导入 {count} 个模板")
# Bundle
bundles_dir = os.path.join(CONFIG_DIR, "bundles")
count = 0
for d in _read_json_files_in_dir(bundles_dir):
if not d.get("id") or _record_exists(db, "insurance_ppt_bundles", "id", d["id"]):
2026-07-23 13:10:50 +08:00
continue
db.session.execute(text(
"INSERT INTO insurance_ppt_bundles "
"(id, display_name, products_json, template_family, status, modules_json) "
"VALUES (:id, :display_name, :products_json, :template_family, :status, :modules_json)"
), {
"id": d["id"],
"display_name": d.get("displayName", ""),
"products_json": json.dumps(d.get("products", []), ensure_ascii=False),
"template_family": d.get("templateFamily", "bundle"),
"status": d.get("status", "active"),
"modules_json": json.dumps(d.get("modules", []), ensure_ascii=False),
})
2026-07-23 13:10:50 +08:00
count += 1
db.session.commit()
logger.info(f"[migrate_014] 导入 {count} 个 Bundle")