110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
"""切片处理器模块 - 负责文本切片和持久化操作"""
|
|
import uuid
|
|
from typing import Any
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.db.models.data_synthesis import (
|
|
DataSynthInstance,
|
|
DataSynthesisFileInstance,
|
|
DataSynthesisChunkInstance,
|
|
)
|
|
from app.db.session import logger
|
|
|
|
|
|
class ChunkProcessor:
|
|
"""切片处理器"""
|
|
|
|
def __init__(self, db: AsyncSession):
|
|
self.db = db
|
|
|
|
async def persist_chunks(
|
|
self,
|
|
synthesis_task: DataSynthInstance,
|
|
file_task: DataSynthesisFileInstance,
|
|
file_id: str,
|
|
chunks: list[Any],
|
|
) -> int:
|
|
"""将切片结果保存到数据库。
|
|
|
|
Args:
|
|
synthesis_task: 合成任务实例
|
|
file_task: 文件任务实例
|
|
file_id: 原始文件ID
|
|
chunks: 切片后的文档列表
|
|
|
|
Returns:
|
|
保存的切片数量
|
|
"""
|
|
for idx, doc in enumerate(chunks, start=1):
|
|
base_metadata = dict(getattr(doc, "metadata", {}) or {})
|
|
base_metadata.update({
|
|
"task_id": str(synthesis_task.id),
|
|
"file_id": file_id
|
|
})
|
|
|
|
chunk_record = DataSynthesisChunkInstance(
|
|
id=str(uuid.uuid4()),
|
|
synthesis_file_instance_id=file_task.id,
|
|
chunk_index=idx,
|
|
chunk_content=doc.page_content,
|
|
chunk_metadata=base_metadata,
|
|
)
|
|
self.db.add(chunk_record)
|
|
|
|
file_task.total_chunks = len(chunks)
|
|
file_task.status = "processing"
|
|
|
|
await self.db.commit()
|
|
await self.db.refresh(file_task)
|
|
|
|
logger.info(f"Persisted {len(chunks)} chunks for file_task={file_task.id}")
|
|
return len(chunks)
|
|
|
|
async def load_chunk_batch(
|
|
self,
|
|
file_task_id: str,
|
|
start_index: int,
|
|
end_index: int,
|
|
) -> list[DataSynthesisChunkInstance]:
|
|
"""按索引范围加载指定文件任务下的一批切片记录。
|
|
|
|
Args:
|
|
file_task_id: 文件任务ID
|
|
start_index: 起始索引(包含)
|
|
end_index: 结束索引(包含)
|
|
|
|
Returns:
|
|
切片实例列表
|
|
"""
|
|
from sqlalchemy import select
|
|
|
|
result = await self.db.execute(
|
|
select(DataSynthesisChunkInstance)
|
|
.where(
|
|
DataSynthesisChunkInstance.synthesis_file_instance_id == file_task_id,
|
|
DataSynthesisChunkInstance.chunk_index >= start_index,
|
|
DataSynthesisChunkInstance.chunk_index <= end_index,
|
|
)
|
|
.order_by(DataSynthesisChunkInstance.chunk_index.asc())
|
|
)
|
|
return list(result.scalars().all())
|
|
|
|
async def count_chunks_for_file(self, synth_file_instance_id: str) -> int:
|
|
"""统计指定任务与文件下的切片总数。
|
|
|
|
Args:
|
|
synth_file_instance_id: 文件实例ID
|
|
|
|
Returns:
|
|
切片总数
|
|
"""
|
|
from sqlalchemy import func, select
|
|
|
|
result = await self.db.execute(
|
|
select(func.count(DataSynthesisChunkInstance.id)).where(
|
|
DataSynthesisChunkInstance.synthesis_file_instance_id == synth_file_instance_id
|
|
)
|
|
)
|
|
return int(result.scalar() or 0)
|