#!/usr/bin/env python3 """ 导入 init/data.json 中的 appcodes / appcodes_kv 编码字典到 sage 数据库。 用法: cd ~/repos/sage py3/bin/python import_codes.py ../supplychain/init/data.json py3/bin/python import_codes.py ../product_management/init/data.json ../supplychain/init/data.json """ import sys import json import os import asyncio import argparse # 修正 venv site-packages 路径(venv 可能是旧版 Python 创建的) _script_dir = os.path.dirname(os.path.abspath(__file__)) _venv_lib = os.path.join(_script_dir, 'py3', 'lib') if os.path.isdir(_venv_lib): for _d in os.listdir(_venv_lib): _sp = os.path.join(_venv_lib, _d, 'site-packages') if os.path.isdir(_sp) and _sp not in sys.path: sys.path.insert(0, _sp) # 添加本地依赖路径(editable install 可能指向 Docker 路径) _repos_dir = os.path.dirname(_script_dir) for _dep in ['apppublic', 'sqlor']: _dep_dir = os.path.join(_repos_dir, _dep) if os.path.isdir(_dep_dir) and _dep_dir not in sys.path: sys.path.insert(0, _dep_dir) from appPublic.jsonConfig import getConfig from sqlor.dbpools import DBPools async def import_data_json(sor, filepath): """将单个 data.json 中的 appcodes 和 appcodes_kv 导入数据库""" with open(filepath, 'r', encoding='utf-8') as f: data = json.load(f) # 导入 appcodes — 支持两种格式: # 格式1: [{"id":..., "name":..., "hierarchy_flg":...}] # 格式2: [{"parentid":..., "parentname":..., "items":[...]}] appcodes = data.get('appcodes', []) codes_count = 0 kv_count = 0 for item in appcodes: # 格式2: parentid/parentname + 内嵌 items if 'parentid' in item and 'items' in item: parentid = item['parentid'] parentname = item.get('parentname', parentid) await sor.sqlExe(""" INSERT INTO appcodes (id, name, hierarchy_flg) VALUES (${id}$, ${name}$, ${hierarchy_flg}$) ON DUPLICATE KEY UPDATE name=VALUES(name), hierarchy_flg=VALUES(hierarchy_flg) """, { 'id': parentid, 'name': parentname, 'hierarchy_flg': item.get('hierarchy_flg', '0') }) codes_count += 1 # 导入内嵌的 kv 条目 for kv_item in item.get('items', []): kv_id = f"{parentid}_{kv_item['k']}" await sor.sqlExe(""" INSERT INTO appcodes_kv (id, parentid, k, v) VALUES (${id}$, ${parentid}$, ${k}$, ${v}$) ON DUPLICATE KEY UPDATE id=VALUES(id), v=VALUES(v) """, { 'id': kv_id, 'parentid': parentid, 'k': kv_item['k'], 'v': kv_item['v'] }) kv_count += 1 # 格式1: 标准 id/name elif 'id' in item: await sor.sqlExe(""" INSERT INTO appcodes (id, name, hierarchy_flg) VALUES (${id}$, ${name}$, ${hierarchy_flg}$) ON DUPLICATE KEY UPDATE name=VALUES(name), hierarchy_flg=VALUES(hierarchy_flg) """, { 'id': item['id'], 'name': item['name'], 'hierarchy_flg': item.get('hierarchy_flg', '0') }) codes_count += 1 print(f" appcodes: {codes_count} 条") # 导入独立 appcodes_kv (格式1兼容) appcodes_kv = data.get('appcodes_kv', []) for item in appcodes_kv: await sor.sqlExe(""" INSERT INTO appcodes_kv (id, parentid, k, v) VALUES (${id}$, ${parentid}$, ${k}$, ${v}$) ON DUPLICATE KEY UPDATE id=VALUES(id), v=VALUES(v) """, { 'id': item['id'], 'parentid': item['parentid'], 'k': item['k'], 'v': item['v'] }) kv_count += 1 if appcodes_kv: print(f" appcodes_kv: {len(appcodes_kv)} 条 (独立)") print(f" appcodes_kv: {kv_count} 条 (合计)") return codes_count, kv_count async def main(): parser = argparse.ArgumentParser(description='导入编码字典到 sage 数据库') parser.add_argument('files', nargs='+', help='init/data.json 文件路径') args = parser.parse_args() # 使用 getConfig() 获取配置,DBPools 初始化数据库池 config = getConfig('.') db = DBPools(config.databases) print(f"连接数据库: sage") total_codes = 0 total_kv = 0 async with db.sqlorContext('sage') as sor: for filepath in args.files: print(f"导入: {filepath}") c, kv = await import_data_json(sor, filepath) total_codes += c total_kv += kv print(f"\n完成! 共导入 appcodes: {total_codes} 条, appcodes_kv: {total_kv} 条") if __name__ == '__main__': asyncio.run(main())