All checks were successful
continuous-integration/drone/push Build is passing
103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
"""Утилиты для работы с SQLAlchemy моделями"""
|
||
|
||
from datetime import date, datetime
|
||
from typing import Any, Optional, TypeVar, Type, cast
|
||
|
||
T = TypeVar('T')
|
||
|
||
def safe_get_column_value(obj: Any, column_name: str, default_value: Optional[T] = None) -> Optional[T]:
|
||
"""
|
||
Безопасное получение значения колонки из SQLAlchemy модели.
|
||
|
||
Args:
|
||
obj: Объект SQLAlchemy модели
|
||
column_name: Имя колонки
|
||
default_value: Значение по умолчанию, если колонка отсутствует или значение None
|
||
|
||
Returns:
|
||
Значение колонки или значение по умолчанию
|
||
"""
|
||
if not hasattr(obj, column_name):
|
||
return default_value
|
||
|
||
value = getattr(obj, column_name)
|
||
if value is None:
|
||
return default_value
|
||
|
||
# Если значение - дата, преобразуем его в Python date
|
||
if hasattr(value, 'isoformat'): # Дата или дата-время
|
||
return cast(T, value)
|
||
|
||
# Для других типов просто возвращаем значение
|
||
return cast(T, value)
|
||
|
||
def safe_int(value: Any, default: int = 0) -> int:
|
||
"""Безопасно преобразует значение в целое число"""
|
||
if value is None:
|
||
return default
|
||
|
||
try:
|
||
return int(value)
|
||
except (ValueError, TypeError):
|
||
return default
|
||
|
||
def safe_str(value: Any, default: str = "") -> str:
|
||
"""Безопасно преобразует значение в строку"""
|
||
if value is None:
|
||
return default
|
||
|
||
try:
|
||
return str(value)
|
||
except (ValueError, TypeError):
|
||
return default
|
||
|
||
def safe_bool(value: Any, default: bool = False) -> bool:
|
||
"""Безопасно преобразует значение в булево значение"""
|
||
if value is None:
|
||
return default
|
||
|
||
if isinstance(value, bool):
|
||
return value
|
||
|
||
try:
|
||
return bool(value)
|
||
except (ValueError, TypeError):
|
||
return default
|
||
|
||
def safe_date(value: Any, default: Optional[date] = None) -> date:
|
||
"""Безопасно преобразует значение в дату"""
|
||
if default is None:
|
||
default = date.today()
|
||
|
||
if value is None:
|
||
return default
|
||
|
||
if isinstance(value, date) and not isinstance(value, datetime):
|
||
return value
|
||
|
||
if isinstance(value, datetime):
|
||
return value.date()
|
||
|
||
try:
|
||
return date.fromisoformat(str(value))
|
||
except (ValueError, TypeError):
|
||
return default
|
||
|
||
def safe_datetime(value: Any, default: Optional[datetime] = None) -> datetime:
|
||
"""Безопасно преобразует значение в дату-время"""
|
||
if default is None:
|
||
default = datetime.now()
|
||
|
||
if value is None:
|
||
return default
|
||
|
||
if isinstance(value, datetime):
|
||
return value
|
||
|
||
if isinstance(value, date):
|
||
return datetime.combine(value, datetime.min.time())
|
||
|
||
try:
|
||
return datetime.fromisoformat(str(value))
|
||
except (ValueError, TypeError):
|
||
return default |