mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
perf(pool): 添加性能计时日志,优化批量删除分批与模型解除关联查询
- 前端批量操作对话框添加 loadAllKeys/executeAction 计时日志 - 后端池账号列表接口和批量删除接口添加分阶段耗时日志 - 批量删除按数据库类型自动选择分批大小,统一前端 batch size 为 2000 - 优化 auto_disassociate 查询:先检查 unlimited key 提前返回,使用 load_only 减少字段加载 - 新增批量操作路由和自动解除关联的单元测试
This commit is contained in:
@@ -8,7 +8,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import cast
|
||||
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from sqlalchemy.orm import Session, joinedload, load_only
|
||||
|
||||
from src.core.exceptions import InvalidRequestException, NotFoundException
|
||||
from src.core.logger import logger
|
||||
@@ -502,9 +502,25 @@ class GlobalModelService:
|
||||
logger.warning(f"Provider {provider_id} not found for auto-disassociation")
|
||||
return results
|
||||
|
||||
# 1. 获取 Provider 下所有活跃 Key 的 allowed_models 并集
|
||||
keys = (
|
||||
db.query(ProviderAPIKey)
|
||||
# 1. 先快速检查是否存在“允许所有模型”的活跃 Key。
|
||||
# 这种情况下无需解除任何关联,避免继续扫描整张 key 表。
|
||||
has_unlimited_key = (
|
||||
db.query(ProviderAPIKey.id)
|
||||
.filter(
|
||||
ProviderAPIKey.provider_id == provider_id,
|
||||
ProviderAPIKey.is_active == True,
|
||||
ProviderAPIKey.allowed_models.is_(None),
|
||||
)
|
||||
.limit(1)
|
||||
.first()
|
||||
is not None
|
||||
)
|
||||
if has_unlimited_key:
|
||||
return results
|
||||
|
||||
# 2. 仅查询活跃 Key 的 allowed_models 列,避免把 api_key/auth_config 等大字段整行拉出。
|
||||
allowed_model_rows = (
|
||||
db.query(ProviderAPIKey.allowed_models)
|
||||
.filter(
|
||||
ProviderAPIKey.provider_id == provider_id,
|
||||
ProviderAPIKey.is_active == True,
|
||||
@@ -512,36 +528,32 @@ class GlobalModelService:
|
||||
.all()
|
||||
)
|
||||
|
||||
# 收集所有 Key 的 allowed_models 并集
|
||||
# 注意:allowed_models 为 null 表示允许所有模型,此时不应解除任何关联
|
||||
all_allowed_models: set[str] = set()
|
||||
has_unlimited_key = False # 是否存在允许所有模型的 Key
|
||||
|
||||
for key in keys:
|
||||
if key.allowed_models is None:
|
||||
# null 表示允许所有模型,直接返回不做任何解除
|
||||
has_unlimited_key = True
|
||||
break
|
||||
if key.allowed_models:
|
||||
all_allowed_models.update(key.allowed_models)
|
||||
|
||||
# 如果存在允许所有模型的 Key,不需要解除任何关联
|
||||
if has_unlimited_key:
|
||||
return results
|
||||
|
||||
# 如果 Provider 无活跃 Key,不做任何解除(保留现有关联)
|
||||
if not keys:
|
||||
if not allowed_model_rows:
|
||||
return results
|
||||
|
||||
# 2. 获取 Provider 当前关联的所有 Model(带 GlobalModel 信息)
|
||||
# 收集所有 Key 的 allowed_models 并集
|
||||
all_allowed_models: set[str] = set()
|
||||
for (allowed_models,) in allowed_model_rows:
|
||||
if isinstance(allowed_models, list) and allowed_models:
|
||||
all_allowed_models.update(m for m in allowed_models if isinstance(m, str))
|
||||
|
||||
# 3. 获取 Provider 当前关联的所有 Model(仅加载判定所需字段)
|
||||
models = (
|
||||
db.query(Model)
|
||||
.options(joinedload(Model.global_model))
|
||||
.options(
|
||||
load_only(Model.id, Model.provider_id, Model.global_model_id),
|
||||
joinedload(Model.global_model).load_only(
|
||||
GlobalModel.id,
|
||||
GlobalModel.name,
|
||||
GlobalModel.config,
|
||||
),
|
||||
)
|
||||
.filter(Model.provider_id == provider_id)
|
||||
.all()
|
||||
)
|
||||
|
||||
# 3. 检查每个 Model 是否还能匹配,收集需要删除的 Model
|
||||
# 4. 检查每个 Model 是否还能匹配,收集需要删除的 Model
|
||||
models_to_delete: list[Model] = []
|
||||
|
||||
for model in models:
|
||||
@@ -577,7 +589,7 @@ class GlobalModelService:
|
||||
if not matched:
|
||||
models_to_delete.append(model)
|
||||
|
||||
# 4. 批量删除不再匹配的 Model(全部成功或全部失败)
|
||||
# 5. 批量删除不再匹配的 Model(全部成功或全部失败)
|
||||
if models_to_delete:
|
||||
try:
|
||||
for model in models_to_delete:
|
||||
|
||||
Reference in New Issue
Block a user