"""回填力量态势详情版本历史(一次脚本)。 对已有 force_situation_details 行但没有任何版本记录的任务,把当前文档补写为版本 1 (created_at 取该行的 updated_at),保证时间轴有初始刻度。 用法(backend 目录):PYTHONPATH=. uv run python scripts/backfill_force_situation_versions.py """ from __future__ import annotations import asyncio async def main() -> int: from sqlalchemy import func, select from deerflow.config import get_app_config from deerflow.persistence.engine import close_engine, get_session_factory, init_engine_from_config from deerflow.persistence.force_situation.model import ( ForceSituationDetailRow, ForceSituationDetailVersionRow, ) config = get_app_config() await init_engine_from_config(config.database) sf = get_session_factory() try: async with sf() as session: rows = (await session.execute(select(ForceSituationDetailRow))).scalars().all() patched = 0 for row in rows: count = ( await session.execute( select(func.count()) .select_from(ForceSituationDetailVersionRow) .where(ForceSituationDetailVersionRow.task_id == row.task_id) ) ).scalar() or 0 if count: continue session.add( ForceSituationDetailVersionRow( task_id=row.task_id, version=1, detail_json=row.detail_json, updated_by=row.updated_by, created_at=row.updated_at, ) ) patched += 1 print(f"回填 {row.task_id} → 版本 1") await session.commit() print(f"完成:回填 {patched} 个任务,跳过 {len(rows) - patched} 个(已有版本)") finally: await close_engine() return 0 if __name__ == "__main__": import sys sys.exit(asyncio.run(main()))