From c7236754148fb0366b5534154ca59718e698b7ce Mon Sep 17 00:00:00 2001 From: Pine Date: Mon, 24 Aug 2026 19:35:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(db):=20AGENT=5FSEED=20=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=20id=20=E7=A7=8D=E5=AD=90=E5=86=B2=E7=AA=81?= =?UTF-8?q?=20=E2=80=94=20=E6=99=BA=E8=83=BD=E4=BD=93=E5=B9=82=E7=AD=89?= =?UTF-8?q?=E6=92=AD=E7=A7=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 _add_agent(按 (id,user_id,port) 已存在则跳过),base 路径/_ensure_extra_demo_users/ _ensure_port_agents 三处统一调用;修复多用户/多端口复用固定 agent id 触发唯一冲突。 验证:临时库 migrate+seed 完整通过且重跑幂等(pine 已灌入)。 --- app/infrastructure/seed.py | 50 ++++++++++++++------------------------ 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/app/infrastructure/seed.py b/app/infrastructure/seed.py index 19608c1..571a5b0 100644 --- a/app/infrastructure/seed.py +++ b/app/infrastructure/seed.py @@ -255,6 +255,20 @@ DEMO_USERS = [ ] +async def _add_agent(session: AsyncSession, seed: dict, user_id: str, port: str | None, now: str) -> None: + """幂等播种单个智能体:按 (id,user_id,port) 已存在则跳过(修全局固定 id 多用户/端口填重)。""" + key = (seed["id"], user_id, port) + if await session.get(Agent, key) is not None: + return + session.add( + Agent(id=seed["id"], user_id=user_id, port=port, name=seed["name"], + description=seed["description"], language=seed.get("language", "zh"), + model_name=seed.get("model_name", ""), deletable=seed.get("deletable", True), + use_fixed_soul=seed.get("use_fixed_soul", False), + created_at=now, updated_at=now) + ) + + async def seed_data(session: AsyncSession) -> None: """幂等种子:仅当 roles 表为空时写入全部基础数据;身份与 OPC 业务始终补种。""" now = utcnow_iso() @@ -317,19 +331,9 @@ async def seed_data(session: AsyncSession) -> None: status="active", token_version=0, created_at=now, updated_at=now, ) ) - # 为每个用户播种默认 + QA 智能体 + # 为每个用户播种默认 + QA 智能体(幂等按 (id,user_id,port=null) 防重) for seed in AGENT_SEED: - session.add( - Agent( - id=seed["id"], user_id=uid, name=seed["name"], - description=seed["description"], - language=seed.get("language", "zh"), - model_name=seed.get("model_name", ""), - deletable=seed.get("deletable", True), - use_fixed_soul=seed.get("use_fixed_soul", False), - created_at=now, updated_at=now, - ) - ) + await _add_agent(session, seed, uid, None, now) await _seed_operator_business(session, now) await _seed_opc_business(session, now) @@ -989,15 +993,7 @@ async def _ensure_extra_demo_users(session: AsyncSession, now: str) -> None: ) ) for seed in AGENT_SEED: - session.add( - Agent( - id=seed["id"], user_id=uid, name=seed["name"], - description=seed["description"], language=seed.get("language", "zh"), - model_name=seed.get("model_name", ""), deletable=seed.get("deletable", True), - use_fixed_soul=seed.get("use_fixed_soul", False), - created_at=now, updated_at=now, - ) - ) + await _add_agent(session, seed, uid, None, now) async def _seed_ecosystem(session: AsyncSession, now: str) -> None: @@ -1049,17 +1045,7 @@ async def _ensure_port_agents(session: AsyncSession, now: str) -> None: (await session.execute(select(Agent.id).where(Agent.user_id == user_id, Agent.port == port))).scalars() ) for seed in AGENT_SEED: - if seed["id"] in existing_ids: - continue # 已存在,跳过(幂等,避免 (id,user_id,port) 唯一冲突) - session.add( - Agent( - id=seed["id"], user_id=user_id, port=port, name=seed["name"], - description=seed["description"], language=seed.get("language", "zh"), - model_name=seed.get("model_name", ""), deletable=seed.get("deletable", True), - use_fixed_soul=seed.get("use_fixed_soul", False), - created_at=now, updated_at=now, - ) - ) + await _add_agent(session, seed, user_id, port, now) async def _seed_org_members(session: AsyncSession, now: str) -> None: