From 71bd44d4dead419f3585e2c19524a166a8c28b84 Mon Sep 17 00:00:00 2001 From: xxm Date: Mon, 17 Aug 2026 16:45:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20batch=5Freassess=20conn=E5=8A=A0timeout+?= =?UTF-8?q?busy=5Ftimeout(=E9=87=8D=E5=81=9A,docstring=E8=AF=AF=E6=94=B9?= =?UTF-8?q?=E5=B7=B2=E4=BF=AE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/profile-scripts/batch_reassess.py | 29 +++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/deploy/profile-scripts/batch_reassess.py b/deploy/profile-scripts/batch_reassess.py index d7644f67..69a1cc6b 100644 --- a/deploy/profile-scripts/batch_reassess.py +++ b/deploy/profile-scripts/batch_reassess.py @@ -25,8 +25,7 @@ STALE_HOURS = 20 # 分析超过20小时视为过期,需要重评 def has_llm_analysis(code): """检查是否为LLM生成的12维分析(>500字)""" - conn = sqlite3.connect(DB, timeout=30) - conn.execute("PRAGMA busy_timeout=30000") + conn = sqlite3.connect(DB) r = conn.execute("SELECT LENGTH(full_analysis) FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone() conn.close() return r and r[0] and r[0] > 500 @@ -38,6 +37,7 @@ def in_cooldown(code): if FORCE_REASSESS: return False conn = sqlite3.connect(DB, timeout=30) + conn.execute("PRAGMA busy_timeout=30000") r = conn.execute("SELECT reassessed_at FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone() conn.close() if not r or not r[0]: @@ -50,7 +50,8 @@ def in_cooldown(code): return False def analysis_stale(code, force_today=False): - """分析是否过期(>STALE_HOURS 或 force_today 时今早4点前未重评)"""sqlite3.connect(DB, timeout=30).connect(DB) + """分析是否过期(>STALE_HOURS 或 force_today 时今早4点前未重评)""" + conn = sqlite3.connect(DB) r = conn.execute("SELECT reassessed_at FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone() conn.close() if not r or not r[0]: @@ -66,7 +67,9 @@ def analysis_stale(code, force_today=False): def get_portfolio(): """从 portfolio_summary 读实时现金/总资产(不再硬编码)""" -sqlite3.connect(DB, timeout=30)nn = sqlite3.connect(DB) + try: + conn = sqlite3.connect(DB, timeout=30) + conn.execute("PRAGMA busy_timeout=30000") r = conn.execute("SELECT cash, total_assets FROM portfolio_summary WHERE id=1").fetchone() conn.close() if r and r[1]: @@ -79,7 +82,7 @@ def collect_data(code): """收集最新数据(含完整策略原文)""" data = {"code": code} - # 从DB读策略(含 full_analysis / changelogsqlite3.connect(DB, timeout=30)vice) + # 从DB读策略(含 full_analysis / changelog_json / position_advice) conn = sqlite3.connect(DB) r = conn.execute("SELECT name, entry_low, entry_high, stop_loss, take_profit, timing_signal, action, rr_ratio, tech_snapshot, sector_context, stock_category, full_analysis, changelog_json, reassessed_at, position_advice FROM holding_strategies WHERE code=? AND status='active'", (code,)).fetchone() if r: @@ -131,7 +134,8 @@ def collect_data(code): # 未映射的股票明确标注"行业未映射"(不让大盘指标伪装成行业信息) _sector_ctx = data.get('sector_context', '') or '' if (not _sector_ctx) or _sector_ctx.startswith('大盘上涨比') or len(_sector_ctx) < 4: - sqlite3.connect(DB, timeout=30) try: + _resolved = "" + try: _sdb = sqlite3.connect(DB) _sr = _sdb.execute("SELECT sector_name FROM stock_sectors WHERE code=? LIMIT 1", (code,)).fetchone() _sdb.close() @@ -140,7 +144,7 @@ def collect_data(code): except Exception: pass _sector_ctx = _resolved if _resolved else "行业未映射(仅大盘环境参考)" - data['sectsqlite3.connect(DB, timeout=30)tor_ctx + data['sector_context'] = _sector_ctx # 大盘 try: conn = sqlite3.connect(DB) @@ -289,7 +293,8 @@ def build_prompt(data): f"禁止出现「已持仓者」视角的建议。") # ── 换仓上下文(2026-07-24 老爸:现金不足时给出具体换股建议)── - _rotation_csqlite3.connect(DB, timeout=30)not data.get('held'): + _rotation_context = "" + if not data.get('held'): try: _rc = sqlite3.connect(DB) _weak = _rc.execute(""" @@ -497,7 +502,8 @@ def parse_response(text): def save_result(code, full_text, parsed, ta_levels=None): """保存LLM结果到DB(先快照再UPDATE)。空分析拒绝写入。 ta_levels: collect_data 计算的确定性技术位,用于止损锚定校验。""" - if not (full_text or "").stsqlite3.connect(DB, timeout=30)t(f" \u274c 拒绝写入空分析(LLM输出为空,保护已有数据)") + if not (full_text or "").strip(): + print(f" \u274c 拒绝写入空分析(LLM输出为空,保护已有数据)") return conn = sqlite3.connect(DB) now = datetime.now().isoformat() @@ -680,9 +686,10 @@ def main(): idx = sys.argv.index("--code") codes = [sys.argv[idx+1]] else: - sqlite3.connect(DB, timeout=30)略 + # 按类型筛选 active 策略 type_map = {"holding": "持仓策略", "watchlist": "自选策略"} - conn = sqlite3.connect(DB) + conn = sqlite3.connect(DB, timeout=30) + conn.execute("PRAGMA busy_timeout=30000") if dtype in type_map: rows = conn.execute( "SELECT code FROM holding_strategies WHERE status='active' AND decision_type=? ORDER BY code",