perf: batch fetch filter functions to eliminate N+1 queries (#21018)
This commit is contained in:
@@ -195,6 +195,26 @@ class FunctionsTable:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_functions_by_ids(
|
||||||
|
self, ids: list[str], db: Optional[Session] = None
|
||||||
|
) -> list[FunctionModel]:
|
||||||
|
"""
|
||||||
|
Batch fetch multiple functions by their IDs in a single query.
|
||||||
|
Returns functions in the same order as the input IDs (None entries filtered out).
|
||||||
|
"""
|
||||||
|
if not ids:
|
||||||
|
return []
|
||||||
|
try:
|
||||||
|
with get_db_context(db) as db:
|
||||||
|
functions = db.query(Function).filter(Function.id.in_(ids)).all()
|
||||||
|
# Create a dict for O(1) lookup
|
||||||
|
func_dict = {f.id: FunctionModel.model_validate(f) for f in functions}
|
||||||
|
# Return in original order, filtering out any not found
|
||||||
|
return [func_dict[id] for id in ids if id in func_dict]
|
||||||
|
except Exception:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def get_functions(
|
def get_functions(
|
||||||
self, active_only=False, include_valves=False, db: Optional[Session] = None
|
self, active_only=False, include_valves=False, db: Optional[Session] = None
|
||||||
) -> list[FunctionModel | FunctionWithValvesModel]:
|
) -> list[FunctionModel | FunctionWithValvesModel]:
|
||||||
|
|||||||
@@ -341,12 +341,8 @@ async def chat_completed(request: Request, form_data: dict, user: Any):
|
|||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
filter_functions = [
|
filter_ids = get_sorted_filter_ids(request, model, metadata.get("filter_ids", []))
|
||||||
Functions.get_function_by_id(filter_id)
|
filter_functions = Functions.get_functions_by_ids(filter_ids)
|
||||||
for filter_id in get_sorted_filter_ids(
|
|
||||||
request, model, metadata.get("filter_ids", [])
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
result, _ = await process_filter_functions(
|
result, _ = await process_filter_functions(
|
||||||
request=request,
|
request=request,
|
||||||
|
|||||||
@@ -1570,12 +1570,8 @@ async def process_chat_payload(request, form_data, user, metadata, model):
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
try:
|
try:
|
||||||
filter_functions = [
|
filter_ids = get_sorted_filter_ids(request, model, metadata.get("filter_ids", []))
|
||||||
Functions.get_function_by_id(filter_id)
|
filter_functions = Functions.get_functions_by_ids(filter_ids)
|
||||||
for filter_id in get_sorted_filter_ids(
|
|
||||||
request, model, metadata.get("filter_ids", [])
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
form_data, flags = await process_filter_functions(
|
form_data, flags = await process_filter_functions(
|
||||||
request=request,
|
request=request,
|
||||||
|
|||||||
Reference in New Issue
Block a user