#!/usr/bin/env python3 """将 decisions.json 全量同步到 SQLite holding_strategies 表""" import json, sqlite3, sys DECISIONS_PATH = '/home/hmo/web-dashboard/data/decisions.json' DB_PATH = '/home/hmo/web-dashboard/data/mofin.db' def main(): # 读 decisions.json with open(DECISIONS_PATH) as f: data = json.load(f) entries = data.get('decisions', []) print(f'Read {len(entries)} entries from decisions.json') db = sqlite3.connect(DB_PATH) # 先清空 holding_strategies(全量重建更干净) db.execute('DELETE FROM holding_strategies') inserted = 0 for d in entries: code = d.get('code') if not code: continue # 从 decisions.json 提取字段,映射到 DB schema sql = '''INSERT INTO holding_strategies ( code, name, version, price, cost, shares, stop_loss, take_profit, entry_low, entry_high, currency, strategy_type, action, timing_signal, rr_ratio, tech_snapshot, stock_category, sector_context, status, trigger_json, changelog_json, source, reason, created_at, updated_at, avg_price, decision_timestamp, note, decision_type ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''' # 确定 type/strategy_type stype = d.get('strategy_type') or d.get('type') or '持仓策略' # decision_type = d.get('decision_type') or stype decision_type = stype vals = ( code, d.get('name', ''), d.get('version', 1), d.get('price'), d.get('cost'), d.get('shares', 0), d.get('stop_loss'), d.get('take_profit'), d.get('entry_low'), d.get('entry_high'), d.get('currency', 'CNY' if code.startswith(('6','0','3','5')) else 'HKD'), stype, d.get('action', ''), d.get('timing_signal', ''), d.get('rr_ratio'), d.get('tech_snapshot'), d.get('stock_category'), d.get('sector_context'), d.get('status', 'active'), json.dumps(d.get('trigger', {}), ensure_ascii=False) if d.get('trigger') else d.get('trigger_json'), json.dumps(d.get('changelog', []), ensure_ascii=False) if d.get('changelog') else d.get('changelog_json'), d.get('source', 'auto'), d.get('reason'), d.get('created_at'), d.get('updated_at'), d.get('avg_price'), d.get('decision_timestamp') or d.get('timestamp'), d.get('note'), decision_type, ) try: db.execute(sql, vals) inserted += 1 except Exception as e: print(f'Error inserting {code} ({d.get("name")}): {e}') db.commit() # 验证 cnt = db.execute('SELECT COUNT(*) FROM holding_strategies').fetchone()[0] active = db.execute('SELECT COUNT(*) FROM holding_strategies WHERE status IN ("active","updated")').fetchone()[0] db.close() print(f'Synced: {inserted} rows inserted') print(f'holding_strategies: {cnt} total, {active} active/updated') return 0 if inserted > 0 else 1 if __name__ == '__main__': sys.exit(main())