perf(backend): 角色/世界观入库改批量——create_many 一次 flush 落全部行

角色入库端点与 toolbox world_entities 入库端点原逐卡/逐条 create(每行一次
SELECT/flush/refresh,N+1 round-trip)。新增 create_many:世界观用 add_all,
角色用一次 IN 查已有名 + 一次 flush(保持 (project_id,name) upsert 幂等与批内
重名去重、保序返回)。单条 create 薄封装 create_many,行为不变(既有调用方/E2E
复用)。复活并复用 CharacterWriteFields、新增 WorldEntityFields 作批量入参。
补两端点「多行一次落库」测试;既有幂等/冲突 gate 测试与 m5 真 pg E2E 全绿。
This commit is contained in:
Yaojia Wang
2026-07-08 12:44:07 +02:00
parent 0892ff6cda
commit bf3dabea82
7 changed files with 221 additions and 71 deletions

View File

@@ -33,6 +33,7 @@ from ww_agents import (
worldbuilder_spec,
)
from ww_core.domain import (
CharacterWriteFields,
CharacterWriteRepo,
ProjectRepo,
RuleWriteRepo,
@@ -372,10 +373,8 @@ async def ingest_characters(
rejected_tables=rejected,
)
created: list[str] = []
for card in allowed.get("characters", []):
view = await char_repo.create(
project_id,
fields = [
CharacterWriteFields(
name=card.name,
role=card.role,
traits=list(card.traits),
@@ -387,7 +386,10 @@ async def ingest_characters(
tags=list(card.tags),
relations=[r.model_dump() for r in card.relations],
)
created.append(view.name)
for card in allowed.get("characters", [])
]
# 批量 upsert一次 flush 落全部),保序返回逐卡 View。
created = [view.name for view in await char_repo.create_many(project_id, fields)]
# 提交边界:网关 ledgerprecheck+ 角色写侧均只 flush → 端点末尾一次 commit。
await session.commit()