3 services are updated

This commit is contained in:
2025-05-13 18:29:02 +03:00
parent cd62d96158
commit 6dfa17c5e6
54 changed files with 1374 additions and 148 deletions

View File

@@ -2,27 +2,24 @@ import arrow
import datetime
from decimal import Decimal
from typing import Any, Optional
from typing import Any, TypeVar, Type, Union, Optional
from sqlalchemy import Column, Integer, String, Float, ForeignKey, UUID, TIMESTAMP, Boolean, SmallInteger, Numeric, func, text, NUMERIC, ColumnExpressionArgument
from sqlalchemy.orm import InstrumentedAttribute, Mapped, mapped_column, Query, Session
from sqlalchemy.sql.elements import BinaryExpression
from sqlalchemy import Column, Integer, String, Float, ForeignKey, UUID, TIMESTAMP, Boolean, SmallInteger, Numeric, func, text, NUMERIC
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy_mixins.serialize import SerializeMixin
from sqlalchemy_mixins.repr import ReprMixin
from sqlalchemy_mixins.smartquery import SmartQueryMixin
from sqlalchemy_mixins.activerecord import ActiveRecordMixin
from sqlalchemy.orm import InstrumentedAttribute, Mapped
from api_controllers.postgres.engine import get_db, Base
class BasicMixin(
Base,
ActiveRecordMixin,
SerializeMixin,
ReprMixin,
SmartQueryMixin,
):
T = TypeVar("CrudMixin", bound="CrudMixin")
class BasicMixin(Base, ActiveRecordMixin, SerializeMixin, ReprMixin, SmartQueryMixin):
__abstract__ = True
__repr__ = ReprMixin.__repr__
@@ -89,6 +86,42 @@ class BasicMixin(
err = e
return False, None
@classmethod
def convert(cls: Type[T], smart_options: dict[str, Any], validate_model: Any = None) -> Optional[tuple[BinaryExpression, ...]]:
"""
Convert smart options to SQLAlchemy filter expressions.
Args:
smart_options: Dictionary of filter options
validate_model: Optional model to validate against
Returns:
Tuple of SQLAlchemy filter expressions or None if validation fails
"""
try:
# Let SQLAlchemy handle the validation by attempting to create the filter expressions
return tuple(cls.filter_expr(**smart_options))
except Exception as e:
# If there's an error, provide a helpful message with valid columns and relationships
valid_columns = set()
relationship_names = set()
# Get column names if available
if hasattr(cls, '__table__') and hasattr(cls.__table__, 'columns'):
valid_columns = set(column.key for column in cls.__table__.columns)
# Get relationship names if available
if hasattr(cls, '__mapper__') and hasattr(cls.__mapper__, 'relationships'):
relationship_names = set(rel.key for rel in cls.__mapper__.relationships)
# Create a helpful error message
error_msg = f"Error in filter expression: {str(e)}\n"
error_msg += f"Attempted to filter with: {smart_options}\n"
error_msg += f"Valid columns are: {', '.join(valid_columns)}\n"
error_msg += f"Valid relationships are: {', '.join(relationship_names)}"
raise ValueError(error_msg) from e
def get_dict(self, exclude_list: Optional[list[InstrumentedAttribute]] = None) -> dict[str, Any]:
"""
Convert model instance to dictionary with customizable fields.
@@ -127,6 +160,7 @@ class BasicMixin(
return {}
class CrudMixin(BasicMixin):
"""
Base mixin providing CRUD operations and common fields for PostgreSQL models.