功能:增加旧测试数据闭包纳入

This commit is contained in:
焦龙言
2026-09-23 13:15:59 +08:00
parent c97f6ed3bd
commit 91cf862248
5 changed files with 1009 additions and 3 deletions
@@ -0,0 +1,100 @@
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from exceptions.exception import ServiceWarning
from module_business.domain.test_batch_graph import BATCH_MODELS, ROOT_TABLES, BatchSelection
from module_business.entity.vo.test_batch_vo import AdoptionRootModel
class TestBatchAdoptionDao:
"""旧数据闭包锁定、展示与批量纳入。"""
@classmethod
async def lock_roots(
cls,
db: AsyncSession,
roots: list[AdoptionRootModel],
) -> None:
requested: dict[str, set[int]] = {}
for root in roots:
requested.setdefault(ROOT_TABLES[root.resource_type], set()).update(root.resource_ids)
for table_name in sorted(requested):
primary_key = BATCH_MODELS[table_name][1]
ids = sorted(requested[table_name])
result = await db.execute(
select(primary_key).where(primary_key.in_(ids)).order_by(primary_key).with_for_update()
)
if {row[0] for row in result.all()} != set(ids):
raise ServiceWarning('', '指定的旧数据不存在')
@classmethod
async def lock_selection(cls, db: AsyncSession, selection: BatchSelection) -> None:
for table_name in sorted(selection):
ids = sorted(selection[table_name])
if not ids:
continue
primary_key = BATCH_MODELS[table_name][1]
result = await db.execute(
select(primary_key).where(primary_key.in_(ids)).order_by(primary_key).with_for_update()
)
if len(result.all()) != len(ids):
raise ServiceWarning('', '预览范围已变化')
@classmethod
async def find_tagged_record(
cls,
db: AsyncSession,
selection: BatchSelection,
) -> tuple[str, int] | None:
for table_name in sorted(selection):
ids = sorted(selection[table_name])
if not ids:
continue
model, primary_key, _ = BATCH_MODELS[table_name]
result = await db.execute(
select(primary_key)
.where(
primary_key.in_(ids),
model.test_batch_id.is_not(None),
)
.order_by(primary_key)
.limit(1)
)
record_id = result.scalar_one_or_none()
if record_id is not None:
return table_name, record_id
return None
@classmethod
async def list_display_keys(
cls,
db: AsyncSession,
selection: BatchSelection,
) -> dict[str, list[str]]:
keys: dict[str, list[str]] = {}
for table_name in BATCH_MODELS:
ids = sorted(selection[table_name])
if not ids:
keys[table_name] = []
continue
_, primary_key, display_column = BATCH_MODELS[table_name]
result = await db.execute(select(display_column).where(primary_key.in_(ids)).order_by(display_column))
keys[table_name] = sorted(str(row[0]) for row in result.all())
return keys
@classmethod
async def set_test_batch_id(
cls,
db: AsyncSession,
table_name: str,
ids: list[int],
batch_id: int,
) -> None:
if not ids:
return
model, primary_key, _ = BATCH_MODELS[table_name]
result = await db.execute(
update(model).where(primary_key.in_(ids), model.test_batch_id.is_(None)).values(test_batch_id=batch_id)
)
if result.rowcount != len(ids):
raise ServiceWarning('', '存在记录已属于其他测试批次')
@@ -149,8 +149,39 @@ class TestBatchDao:
async def count_owned_rows(cls, db: AsyncSession, batch_id: int) -> dict[str, int]:
counts: dict[str, int] = {}
for model in _BATCH_OWNED_MODELS:
result = await db.execute(
select(func.count()).select_from(model).where(model.test_batch_id == batch_id)
)
result = await db.execute(select(func.count()).select_from(model).where(model.test_batch_id == batch_id))
counts[model.__tablename__] = result.scalar() or 0
return counts
@classmethod
async def store_preview(
cls,
db: AsyncSession,
batch: BizTestBatch,
*,
action: str,
token_hash: str,
scope_hash: str,
expires_at: datetime,
update_by: str,
update_time: datetime,
) -> None:
"""在已锁定的批次对象上保存一次性预览状态。"""
batch.preview_action = action
batch.preview_token_hash = token_hash
batch.preview_scope_hash = scope_hash
batch.preview_expires_at = expires_at
batch.update_by = update_by
batch.update_time = update_time
@classmethod
async def clear_preview(
cls,
db: AsyncSession,
batch: BizTestBatch,
) -> None:
"""消费已锁定批次上的预览令牌与范围摘要。"""
batch.preview_action = None
batch.preview_token_hash = None
batch.preview_scope_hash = None
batch.preview_expires_at = None