""" Portal 一键部署 — 初始化数据 从 cms 模块的 init/data.yaml 加载所有初始数据: - appcodes (枚举编码) - appcodes_kv (枚举值) - cms_categories (默认分类) - cms_site_config (默认站点配置) - cms_sections (默认栏目配置) - dd_approval_configs (默认审批配置) 用法: cd ~/repos/portal && py3/bin/python init_data.py """ import os, sys, json app_dir = os.path.dirname(os.path.abspath(__file__)) root_dir = app_dir sys.path.insert(0, root_dir) # 读取YAML try: import yaml except ImportError: # 简单YAML解析(fallback) yaml = None CMS_DIR = os.path.expanduser("~/cms") DATA_FILE = os.path.join(CMS_DIR, "init", "data.yaml") def load_yaml_simple(path): """简单YAML加载(仅支持本文件用到的结构)""" if yaml: with open(path, 'r', encoding='utf-8') as f: return yaml.safe_load(f) else: # 用json做fallback - 要求data文件也有json版本 json_path = path.replace('.yaml', '.json') if os.path.exists(json_path): with open(json_path, 'r', encoding='utf-8') as f: return json.load(f) raise ImportError("需要PyYAML: pip install pyyaml") def main(): print("=== Portal 一键部署 — 初始化数据 ===") print(f"CMS模块: {CMS_DIR}") print(f"数据文件: {DATA_FILE}") print() if not os.path.exists(DATA_FILE): print(f"ERROR: 数据文件不存在: {DATA_FILE}") sys.exit(1) # 加载YAML data = load_yaml_simple(DATA_FILE) # 连接数据库 from sqlor.dbpools import DBPools from appPublic.uniqueID import getID from ahserver.serverenv import ServerEnv from appPublic.jsonConfig import getConfig from appPublic.log import MyLogger # 初始化日志和配置 MyLogger(getConfig()) db = DBPools(getConfig().databases) dbname = 'ocai_cms' import asyncio async def insert_data(): async with db.sqlorContext(dbname) as sor: # 1. appcodes appcodes = data.get('appcodes', []) if appcodes: print(f"\n--- appcodes ({len(appcodes)} 条) ---") for item in appcodes: item.setdefault('id', getID()) item.setdefault('org_id', '0') try: # 检查是否已存在 existing = await sor.R('appcodes', {'id': item['id']}) if not existing: await sor.C('appcodes', item) print(f" ✓ {item['id']} - {item.get('name', '')}") else: print(f" · {item['id']} (已存在)") except Exception as e: print(f" ✗ {item.get('id', '?')}: {e}") # 2. appcodes_kv appcodes_kv = data.get('appcodes_kv', []) if appcodes_kv: print(f"\n--- appcodes_kv ({len(appcodes_kv)} 条) ---") for item in appcodes_kv: item.setdefault('id', getID()) item.setdefault('org_id', '0') try: existing = await sor.R('appcodes_kv', {'id': item['id']}) if not existing: await sor.C('appcodes_kv', item) print(f" ✓ {item['id']} ({item.get('parentid', '')}.{item.get('k', '')} = {item.get('v', '')})") else: print(f" · {item['id']} (已存在)") except Exception as e: print(f" ✗ {item.get('id', '?')}: {e}") # 3. cms_categories categories = data.get('cms_categories', []) if categories: print(f"\n--- cms_categories ({len(categories)} 条) ---") for item in categories: item.setdefault('id', getID()) try: existing = await sor.R('cms_categories', {'id': item['id']}) if not existing: await sor.C('cms_categories', item) print(f" ✓ {item['id']} - {item.get('name', '')} [{item.get('content_type', '')}]") else: print(f" · {item['id']} (已存在)") except Exception as e: print(f" ✗ {item.get('id', '?')}: {e}") # 4. cms_site_config configs = data.get('cms_site_config', []) if configs: print(f"\n--- cms_site_config ({len(configs)} 条) ---") for item in configs: item.setdefault('id', getID()) try: existing = await sor.R('cms_site_config', {'id': item['id']}) if not existing: await sor.C('cms_site_config', item) print(f" ✓ {item['id']} ({item.get('config_group', '')}.{item.get('config_key', '')})") else: print(f" · {item['id']} (已存在)") except Exception as e: print(f" ✗ {item.get('id', '?')}: {e}") # 5. cms_sections sections = data.get('cms_sections', []) if sections: print(f"\n--- cms_sections ({len(sections)} 条) ---") for item in sections: item.setdefault('id', getID()) try: existing = await sor.R('cms_sections', {'id': item['id']}) if not existing: await sor.C('cms_sections', item) print(f" ✓ {item['id']} - {item.get('title', '')} [{item.get('section_type', '')}]") else: print(f" · {item['id']} (已存在)") except Exception as e: print(f" ✗ {item.get('id', '?')}: {e}") # 6. dd_approval_configs dd_configs = data.get('dd_approval_configs', []) if dd_configs: print(f"\n--- dd_approval_configs ({len(dd_configs)} 条) ---") for item in dd_configs: item.setdefault('id', getID()) try: existing = await sor.R('dd_approval_configs', {'id': item['id']}) if not existing: await sor.C('dd_approval_configs', item) print(f" ✓ {item['id']} - {item.get('biz_type', '')}") else: print(f" · {item['id']} (已存在)") except Exception as e: print(f" ✗ {item.get('id', '?')}: {e}") total = len(appcodes) + len(appcodes_kv) + len(categories) + len(configs) + len(sections) + len(dd_configs) print(f"\n=== 完成: 处理 {total} 条初始数据 ===") asyncio.run(insert_data()) if __name__ == '__main__': main()