SearchFilter

Bases: QueryClause

A class representing a search filter for SQLAlchemy queries. This class extends the QueryClause class and adds attributes for the operator, field, and value of the filter.

An instance of this class represents a single filter condition that can be applied to a call to the filters parameter of any method of a SqlRepository subclass. Keep in mind that this filters parameter is expected to be a sequence of SearchFilter instances, so multiple filters can be applied to a query by including multiple instances of this class in the sequence.

Use a FilterOperator class to define AND or OR combinations of multiple SearchFilter instances for more complex filtering logic.

Attributes:
  • op (Operator) –

    An instance of the Operator enum specifying the type of comparison to be performed.

  • field (str | InstrumentedAttribute[Any]) –

    A string representing the name of the field to filter on, or an InstrumentedAttribute from SQLAlchemy representing the field.

  • value (Any) –

    The value to compare the field against in the filter.

Source code in src/alpha/infra/models/search_filter.py
@dataclass
class SearchFilter(QueryClause):
    """A class representing a search filter for SQLAlchemy queries. This class
    extends the `QueryClause` class and adds attributes for the operator,
    field, and value of the filter.

    An instance of this class represents a single filter condition that can be
    applied to a call to the `filters` parameter of any method of a
    `SqlRepository` subclass. Keep in mind that this `filters` parameter is
    expected to be a sequence of `SearchFilter` instances, so multiple filters
    can be applied to a query by including multiple instances of this class in
    the sequence.

    Use a FilterOperator class to define AND or OR combinations of multiple
    SearchFilter instances for more complex filtering logic.

    Attributes
    ----------
    op
        An instance of the `Operator` enum specifying the type of comparison to
        be performed.
    field
        A string representing the name of the field to filter on, or an
        `InstrumentedAttribute` from SQLAlchemy representing the field.
    value
        The value to compare the field against in the filter.
    """

    op: Operator = Operator.EQ
    field: str | InstrumentedAttribute[Any] = ""
    value: Any = ""

    def __post_init__(self) -> None:
        """Post-initialization method to set up the search filter. This method
        calls the parent class's post-initialization method and then determines
        the appropriate subclass based on the operator attribute.
        """
        super().__post_init__()
        self.__class__ = self._get_filter_class()  # type: ignore

    @property
    def filter_statement(
        self,
    ) -> BinaryExpression[Any] | ColumnOperators:
        """Returns the filter statement

        Returns
        -------
        BinaryExpression | ColumnOperators
            Filter statement

        Raises
        ------
        NotImplementedError
            When called directly
        """
        raise NotImplementedError

    def _get_filter_class(self) -> type["SearchFilter"]:
        match self.op:
            case Operator.LT:
                return LessThanFilter
            case Operator.LTE:
                return LessThanEqualsFilter
            case Operator.EQ:
                return EqualsFilter
            case Operator.NEQ:
                return NotEqualsFilter
            case Operator.GT:
                return GreaterThanFilter
            case Operator.GTE:
                return GreaterThanEqualsFilter
            case Operator.IN:
                return InFilter
            case Operator.NIN:
                return NotInFilter
            case Operator.LIKE:
                return LikeFilter
            case Operator.NLIKE:
                return NotLikeFilter
            case Operator.ILIKE:
                return InsensitiveLikeFilter
            case Operator.NILIKE:
                return InsensitiveNotLikeFilter
            case Operator.STARTSWITH:
                return StartsWithFilter
            case Operator.NSTARTSWITH:
                return NotStartsWithFilter
            case Operator.ISTARTSWITH:
                return InsensitiveStartsWithFilter
            case Operator.NISTARTSWITH:
                return InsensitiveNotStartsWithFilter
            case Operator.ENDSWITH:
                return EndsWithFilter
            case Operator.NENDSWITH:
                return NotEndsWithFilter
            case Operator.IENDSWITH:
                return InsensitiveEndsWithFilter
            case Operator.NIENDSWITH:
                return InsensitiveNotEndsWithFilter
            case Operator.CONTAINS:
                return ContainsFilter
            case Operator.NCONTAINS:
                return NotContainsFilter
            case Operator.ICONTAINS:
                return InsensitiveContainsFilter
            case Operator.NICONTAINS:
                return InsensitiveNotContainsFilter

    def _parse_list(self, obj: str | list[str] | Any) -> list[str]:
        if isinstance(obj, list):
            return obj  # type: ignore
        if isinstance(obj, str):
            return obj.split(",")
        return [obj]

filter_statement property

filter_statement

Returns the filter statement

Returns:
  • BinaryExpression | ColumnOperators

    Filter statement

Raises:
  • NotImplementedError

    When called directly

Methods:

__post_init__

__post_init__()

Post-initialization method to set up the search filter. This method calls the parent class's post-initialization method and then determines the appropriate subclass based on the operator attribute.

Source code in src/alpha/infra/models/search_filter.py
def __post_init__(self) -> None:
    """Post-initialization method to set up the search filter. This method
    calls the parent class's post-initialization method and then determines
    the appropriate subclass based on the operator attribute.
    """
    super().__post_init__()
    self.__class__ = self._get_filter_class()  # type: ignore