Coverage for postrfp / ref / service / helpers.py: 100%
13 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-03 01:35 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-03 01:35 +0000
1from typing import TypeVar, Any
2from sqlalchemy.orm import Session
5T = TypeVar("T")
8def fetch_related_items(
9 session: Session,
10 model_class: Any,
11 ids: list[int],
12 error_name: str,
13 require_all: bool = True,
14) -> list[T]:
15 """
16 Fetch related items in a single query and verify all were found
18 Args:
19 session: SQLAlchemy session
20 model_class: SQLAlchemy model class to query (must have an 'id' attribute)
21 ids: List of IDs to fetch
22 error_name: Name to use in error messages
23 require_all: Whether to verify all requested IDs were found
25 Returns:
26 List of found items
28 Raises:
29 ValueError: If require_all is True and any requested IDs were not found
30 """
31 if not ids:
32 return []
34 items = session.query(model_class).filter(model_class.id.in_(ids)).all()
36 # Optionally verify all requested items were found
37 if require_all:
38 found_ids = {item.id for item in items}
39 missing_ids = set(ids) - found_ids
40 if missing_ids:
41 raise ValueError(f"{error_name} with IDs {missing_ids} not found")
43 return items