128 lines
3.5 KiB
Python
128 lines
3.5 KiB
Python
"""
|
|
Response handler for PostgreSQL query results.
|
|
|
|
This module provides a wrapper class for SQLAlchemy query results,
|
|
adding convenience methods for accessing data and managing query state.
|
|
"""
|
|
|
|
from typing import Any, Dict, Optional, TypeVar, Generic, Union
|
|
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.orm import Query
|
|
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
class PostgresResponse(Generic[T]):
|
|
"""
|
|
Wrapper for PostgreSQL/SQLAlchemy query results.
|
|
|
|
Attributes:
|
|
metadata: Additional metadata for the query
|
|
|
|
Properties:
|
|
count: Total count of results
|
|
query: Get query object
|
|
as_dict: Convert response to dictionary format
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
pre_query: Query,
|
|
query: Query,
|
|
model,
|
|
is_array: bool = True,
|
|
metadata: Any = None,
|
|
):
|
|
self._core_class = model
|
|
self._is_list = is_array
|
|
self._query = query
|
|
self._pre_query = pre_query
|
|
self._count: Optional[int] = None
|
|
self.metadata = metadata
|
|
|
|
@property
|
|
def core_class(self):
|
|
"""Get query object."""
|
|
return self._core_class
|
|
|
|
@property
|
|
def data(self) -> Union[T, list[T]]:
|
|
"""Get query results."""
|
|
if not self.is_list:
|
|
first_item = self._query.first()
|
|
return first_item if first_item else None
|
|
return self._query.all() if self._query.all() else []
|
|
|
|
@property
|
|
def data_as_dict(self) -> Union[Dict[str, Any], list[Dict[str, Any]]] | None:
|
|
"""Get query results as dictionary."""
|
|
if not self.count:
|
|
return None
|
|
if self.is_list:
|
|
first_item = self._query.first()
|
|
return first_item.get_dict() if first_item.first() else None
|
|
all_items = self._query.all()
|
|
return [result.get_dict() for result in all_items] if all_items else []
|
|
|
|
@property
|
|
def total_count(self) -> int:
|
|
"""Lazy load and return total count of results."""
|
|
return self._pre_query.count() if self._pre_query else 0
|
|
|
|
@property
|
|
def count(self) -> int:
|
|
"""Lazy load and return total count of results."""
|
|
return self._query.count()
|
|
|
|
@property
|
|
def core_query(self) -> str:
|
|
"""Get query object."""
|
|
return str(self._query)
|
|
|
|
@property
|
|
def query(self) -> Query:
|
|
"""Get query object."""
|
|
return self._query
|
|
|
|
@property
|
|
def is_list(self) -> bool:
|
|
"""Check if response is a list."""
|
|
return self._is_list
|
|
|
|
@property
|
|
def as_dict(self) -> Dict[str, Any]:
|
|
"""Convert response to dictionary format."""
|
|
if isinstance(self.data, list):
|
|
return {
|
|
"metadata": self.metadata,
|
|
"is_list": self._is_list,
|
|
"query": str(self.query),
|
|
"count": self.count,
|
|
"data": [result.get_dict() for result in self.data],
|
|
}
|
|
return {
|
|
"metadata": self.metadata,
|
|
"is_list": self._is_list,
|
|
"query": str(self.query),
|
|
"count": self.count,
|
|
"data": self.data.get_dict() if self.data else {},
|
|
}
|
|
|
|
|
|
class EndpointResponse(BaseModel):
|
|
completed: bool = True
|
|
message: str = "Success"
|
|
pagination_result: Any
|
|
|
|
@property
|
|
def response(self):
|
|
"""Convert response to dictionary format."""
|
|
return {
|
|
"completed": self.completed,
|
|
"message": self.message,
|
|
"data": self.pagination_result.data,
|
|
"pagination": self.pagination_result.pagination.as_dict(),
|
|
}
|