解决了部分detail load效率问题和load失败终止pipeline问题

This commit is contained in:
strepsiades
2026-04-02 14:35:28 +08:00
parent bb8ea931b5
commit 74df53889c
14 changed files with 626 additions and 64 deletions
@@ -13,26 +13,54 @@ from ...common.sync_node import SyncNode
from ...datasource.api.errors import ERROR_NODE_DATA_NONE, ERROR_ID_NOT_FOUND
from .sync_node import PersonnelDetailSyncNode
from schemas.power.power_detail import PowerDetail, PowerDetailCreate, PowerDetailUpdate
from ..project.api_handler import ProjectApiHandler
class PersonnelDetailApiHandler(BaseApiHandler):
"""人员明细 API Handler"""
def __init__(self):
super().__init__()
def __init__(self, **handler_config: Any):
super().__init__(**handler_config)
self._node_type = "personnel_detail"
self._node_class = PersonnelDetailSyncNode
self._schema = PowerDetail
self.update_schemas = [PowerDetailCreate, PowerDetailUpdate]
async def load(self) -> List[SyncNode]:
"""加载人员明细列表(依赖 Personnel)"""
def _use_aggregate_load(self) -> bool:
return str(self.handler_config.get("load_method", "legacy")).lower() == "aggregate"
async def _load_via_project_aggregate(self) -> List[SyncNode]:
projects = self._collection.filter(node_type="project")
project_ids = [project.data_id for project in projects if project.data_id]
if not project_ids:
return []
all_details: List[SyncNode] = []
aggregate_limit = int(self.handler_config.get("aggregate_limit", 10000))
for project_id in project_ids:
aggregate = await ProjectApiHandler.get_aggregate(
self.api_client,
project_id,
domains=["power_details"],
limit=aggregate_limit,
)
truncated = set(aggregate.get("meta", {}).get("truncated_domains", []))
if "power_details" in truncated:
raise RuntimeError(
f"project aggregate truncated domain power_details for project {project_id}"
)
for detail_data in aggregate.get("data", {}).get("power_details", []):
validated = PowerDetail.model_validate(detail_data)
all_details.append(self._create_node(validated.model_dump()))
return all_details
async def _load_via_legacy_list(self) -> List[SyncNode]:
personnel_list = self._collection.filter(node_type="personnel")
personnel_ids = [p.data_id for p in personnel_list if p.data_id]
if not personnel_ids:
return []
all_details = []
for personnel_id in personnel_ids:
try:
@@ -42,9 +70,15 @@ class PersonnelDetailApiHandler(BaseApiHandler):
all_details.append(self._create_node(validated.model_dump()))
except Exception as e:
print(f"❌ Failed to load personnel details for {personnel_id}: {e}")
return all_details
async def load(self) -> List[SyncNode]:
"""加载人员明细列表(依赖 Personnel)"""
if self._use_aggregate_load():
return await self._load_via_project_aggregate()
return await self._load_via_legacy_list()
async def create_all(self, nodes: List[SyncNode]) -> List[TaskResult]:
"""批量创建人员明细"""
results = []