"""现场重跑 enrichment_loop 查询 + 看排序""" import os, paramiko, base64 c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect("207.57.129.228", port=19717, username="root", password=os.environ["REMOTE_PASS"], timeout=30, allow_agent=False, look_for_keys=False) py = r"""import asyncio, sys sys.path.insert(0, '/app') from sqlalchemy import select from app.database import AsyncSessionLocal from app.models.article import Article async def main(): async with AsyncSessionLocal() as session: # 跟 enrichment_loop.py:410 一样的查询 rows = (await session.execute( select(Article) .where(Article.translation_status == "ok", Article.title_zh.is_not(None)) .order_by(Article.id.asc()) .limit(160) )).scalars() candidates = list(rows) # 状态分布 cls_dist = {} for a in candidates: s = a.classify_status or "NULL" cls_dist[s] = cls_dist.get(s, 0) + 1 print(f"candidates={len(candidates)}") print(f"classify 分布: {cls_dist}") # 头 5 篇的 id + status for a in candidates[:5]: print(f" id={a.id} cls={a.classify_status} fmt={a.format_status} cmt={a.commentary_status} img={a.image_ai_status}") # 尾 5 篇 print("--- last 5 ---") for a in candidates[-5:]: print(f" id={a.id} cls={a.classify_status} fmt={a.format_status} cmt={a.commentary_status} img={a.image_ai_status}") # todo 计算 todo = [] for a in candidates: statuses = [a.format_status or "pending", a.classify_status or "pending", a.image_ai_status or "pending", a.commentary_status or "pending"] if any(s in ("pending","failed","n/a") for s in statuses): todo.append(a.id) if len(todo) >= 8: break print(f"todo={len(todo)} ids={todo}") asyncio.run(main()) """ b64 = base64.b64encode(py.encode("utf-8")).decode("ascii") si, so, se = c.exec_command(f"bash -lc 'echo {b64} | base64 -d > /srv/news/diag.py'", timeout=10) so.read() # 复制进 worker 容器 si, so, se = c.exec_command("bash -lc 'cd /srv/news && CID=$(docker compose ps -q worker) && docker cp diag.py $CID:/tmp/diag.py && docker compose exec -T worker python /tmp/diag.py 2>&1 | head -30'", timeout=30) print(so.read().decode(errors="replace")) c.close()