MagicDotPath classes

BaseMagicDotPath

Abstract base for Magical object with operator methods.

Inspired by The very useful DotMap module this object allow to write predicate in the lambda function used in SQL clause like .select() or .join(). This is very useful to express SQL constraint.

See the LINQ documentation for more in depth explanation.

Source code in py_linq_sql/utils/classes/magicdotpath.py
class BaseMagicDotPath:
    """
    Abstract base for Magical object with operator methods.

    Inspired by The very useful [DotMap module](https://github.com/drgrib/dotmap) this
    object allow to write predicate in the lambda function used in SQL clause like
    `.select()` or `.join()`. This is very useful to express SQL constraint.

    See the LINQ documentation for more in depth explanation.

    """

    def __getattr__(self, attribute_name: str) -> BaseMagicDotPath:
        """
        Get attribute in a list for a MagicDotPath objects.

        Args:
            attribute_name: Names of all attributes.

        Returns:
            A MagicDotPath objects with attributes names in attributes list.

        Raises:
            NotImplementedError: This function is just a wrapper for the subclasses.
        """
        # No cover because is just a wrapper for subclasses.
        raise NotImplementedError  # pragma: no cover

    def __getitem__(self, attribute_name: str) -> BaseMagicDotPath:
        """
        Get items in a list for a MagicDotPath objects.

        Args:
            attribute_name: Names of all attributes.

        Returns:
            A MagicDotPath objects with attributes names in attributes list.

        Raises:
            NotImplementedError: This function is just a wrapper for the subclasses.
        """
        # No cover because is just a wrapper for subclasses.
        raise NotImplementedError  # pragma: no cover

    def _get_number_operator(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
        operator: _OPERATORTYPE,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a number operator.

        Args:
            other: Second objects for the comparison.
            operator: type of the operator.

        Returns:
            A MagicDotPathWithOp contains two operand and an operator
            with the correct type.

        Raises:
            TypeOperatorError: If the type of other is not accepted by the function.
            Accepted type: int, float, decimal, BaseMagicDotPath.
        """
        other_type: Type[Any]
        match other:
            case float():
                other_type = float
            case int():
                other_type = int
            case Decimal():
                other_type = Decimal
            case BaseMagicDotPath():
                other_type = BaseMagicDotPath
            case _:
                raise TypeOperatorError(
                    [int, float, Decimal, BaseMagicDotPath],
                    type(other),
                )
        return MagicDotPathWithOp(
            operand_1=self,
            operator=operator,
            operand_2=other,
            my_type=other_type,
        )

    def _get_generic_operator(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
        operator: _OPERATORTYPE,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a generic operator.

        Args:
            other: Second objects for the comparison.
            operator: type of the operator.

        Returns:
            A MagicDotPathWithOp contains two operand and an operator
            with the correct type.

        Raises:
            TypeOperatorError: If the type of other is not accepted by the function.
            Accepted type: int, float, decimal, str, list, dict, BaseMagicDotPath.
        """
        other_type: Type[Any] | None = None
        match other:
            case float():
                other_type = float
            case bool():
                other_type = bool
            case int():
                other_type = int
            case Decimal():
                other_type = Decimal
            case str():
                other_type = str
            case list():
                if operator == OperatorType.IN:
                    other_type = str
                else:
                    other_type = list
            case dict():
                other_type = dict
            case BaseMagicDotPath():
                other_type = BaseMagicDotPath
            case _:
                raise TypeOperatorError(
                    [float, int, Decimal, str, list, dict, bool, BaseMagicDotPath],
                    type(other),
                )
        return MagicDotPathWithOp(
            operand_1=self,
            operator=operator,
            operand_2=other,
            my_type=other_type,
        )

    def _get_one_operand_operator(self, operator: _OPERATORTYPE) -> MagicDotPathWithOp:
        """
        Get the operator for single operand MagicDotPathWithOp (~, abs, ...).

        Args:
            operator: The operator we want.

        Returns:
            A MagicDotPathWithOp contains an operand and an operator, operand_2 is None,
            with `~(x.data.obj.name) #not x.data.obj.name` we have only one operand and
            `my_type` is NoneType therefore.
        """
        return MagicDotPathWithOp(
            operand_1=self,
            operator=operator,
            operand_2=None,
            my_type=NoneType,
        )

    def __gt__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `>` operator and the correct types.

        Types are integer, float, Decimal or BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.GT)

    def __lt__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `<` operator and the correct types.

        Types are integer, float, Decimal or BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.LT)

    def __ge__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `>=` operator and the correct types.

        Types are integer, float, Decimal or BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.GE)

    def __le__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `<=` operator and the correct types.

        Types are integer, float, Decimal or BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.LE)

    def __eq__(  # type: ignore[override]
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `=` operator and the correct types.

        Types are integer, float, Decimal, string, list, dict, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_generic_operator`
        """
        return self._get_generic_operator(other, OperatorType.EQ)

    def __ne__(  # type: ignore[override]
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `<>` operator and the correct types.

        Types are integer, float, Decimal, string, list, dict, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_generic_operator`
        """
        return self._get_generic_operator(other, OperatorType.NE)

    def __add__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `+` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.ADD)

    def __radd__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `+` operator and the correct types.

        This operator is useful when we make `8 + MagicDotPath`
        and not `MagicDotPath + 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self.__add__(other)

    def __sub__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `-` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.SUB)

    def __rsub__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `-` operator and the correct types.

        This operator is useful when we make `8 - MagicDotPath`
        and not `MagicDotPath - 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        mdp_with_op = self._get_number_operator(self, OperatorType.SUB)
        mdp_with_op.operand_1 = other
        return mdp_with_op

    def __mul__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `*` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.MUL)

    def __rmul__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `*` operator and the correct types.

        This operator is useful when we make `8 * MagicDotPath`
        and not `MagicDotPath * 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self.__mul__(other)

    def __truediv__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `/` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.TRUEDIV)

    def __rtruediv__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `/` operator and the correct types.

        This operator is useful when we make `8 / MagicDotPath`
        and not `MagicDotPath / 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        mdp_with_op = self._get_number_operator(self, OperatorType.TRUEDIV)
        mdp_with_op.operand_1 = other
        return mdp_with_op

    def __mod__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `%` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.MOD)

    def __rmod__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `%` operator and the correct types.

        This operator is useful when we make `8 % MagicDotPath`
        and not `MagicDotPath % 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        mdp_with_op = self._get_number_operator(self, OperatorType.MOD)
        mdp_with_op.operand_1 = other
        return mdp_with_op

    def __and__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `AND` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_generic_operator`
        """
        return self._get_generic_operator(other, OperatorType.AND)

    def __rand__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `AND` operator and the correct types.

        This operator is useful when we make `8 & MagicDotPath`
        and not `MagicDotPath & 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_generic_operator`
        """
        return self.__and__(other)

    def __or__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `OR` operator and the correct types.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_generic_operator`
        """
        return self._get_generic_operator(other, OperatorType.OR)

    def __ror__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `OR` operator and the correct types.

        This operator is useful when we make `8 | MagicDotPath`
        and not `MagicDotPath | 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_generic_operator`
        """
        return self.__or__(other)

    def __invert__(self) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `NOT` operator.

        Returns:
            MagicDotPathWithOp.
        """
        return self._get_one_operand_operator(OperatorType.INVERT)

    def __pow__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `^` operator.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        return self._get_number_operator(other, OperatorType.POW)

    def __rpow__(
        self,
        other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
    ) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `^` operator and the correct types.

        This operator is useful when we make `8 ^ MagicDotPath`
        and not `MagicDotPath ^ 8`.

        Types are integer, float, Decimal, BaseMagicDotPath.

        Args:
            other: The value at which the comparison is made.

        Returns:
            MagicDotPathWithOp.

        Raises:
            TypeOperatorError: Indirect raise by `_get_number_operator`
        """
        mdp_with_op = self._get_number_operator(self, OperatorType.POW)
        mdp_with_op.operand_1 = other
        return mdp_with_op

    def __abs__(self) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `abs()` operator.

        Returns:
            MagicDotPathWithOp.
        """
        return self._get_one_operand_operator(OperatorType.ABS)

    def __pos__(self) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `+` operator.

        Returns:
            MagicDotPathWithOp.
        """
        return self._get_one_operand_operator(OperatorType.POS)

    def __neg__(self) -> MagicDotPathWithOp:
        """
        Get a MagicDotPathWithOp objects with a `-` operator.

        Returns:
            MagicDotPathWithOp.
        """
        return self._get_one_operand_operator(OperatorType.NEG)

    def jsonb_path(self, as_str: bool) -> str:
        """
        Get the corresponding jsonb path from a MagicDotPath.

        Args:
            as_str: Boolean to force the request with json in str.

        Returns:
            A path with the correct jsonb syntax.

        Raises:
            NotImplementedError: This function is just a wrapper for the subclasses.
        """
        # No cover because is just a wrapper for subclasses.
        raise NotImplementedError  # pragma: no cover

    def col_name(self) -> str:
        """
        Get the corresponding column name form a MagicDotPath.

        Returns:
            A column name with the correct format.

        Raises:
            NotImplementedError: This function is just a wrapper for the subclasses.
        """
        # No cover because is just a wrapper for subclasses.
        raise NotImplementedError  # pragma: no cover

__abs__(self) special

Get a MagicDotPathWithOp objects with a abs() operator.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __abs__(self) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `abs()` operator.

    Returns:
        MagicDotPathWithOp.
    """
    return self._get_one_operand_operator(OperatorType.ABS)

__add__(self, other) special

Get a MagicDotPathWithOp objects with a + operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __add__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `+` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.ADD)

__and__(self, other) special

Get a MagicDotPathWithOp objects with a AND operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_generic_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __and__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `AND` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_generic_operator`
    """
    return self._get_generic_operator(other, OperatorType.AND)

__eq__(self, other) special

Get a MagicDotPathWithOp objects with a = operator and the correct types.

Types are integer, float, Decimal, string, list, dict, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_generic_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __eq__(  # type: ignore[override]
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `=` operator and the correct types.

    Types are integer, float, Decimal, string, list, dict, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_generic_operator`
    """
    return self._get_generic_operator(other, OperatorType.EQ)

__ge__(self, other) special

Get a MagicDotPathWithOp objects with a >= operator and the correct types.

Types are integer, float, Decimal or BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __ge__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `>=` operator and the correct types.

    Types are integer, float, Decimal or BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.GE)

__getattr__(self, attribute_name) special

Get attribute in a list for a MagicDotPath objects.

Parameters:
  • attribute_name (str) – Names of all attributes.

Returns:
  • BaseMagicDotPath – A MagicDotPath objects with attributes names in attributes list.

Exceptions:
  • NotImplementedError – This function is just a wrapper for the subclasses.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __getattr__(self, attribute_name: str) -> BaseMagicDotPath:
    """
    Get attribute in a list for a MagicDotPath objects.

    Args:
        attribute_name: Names of all attributes.

    Returns:
        A MagicDotPath objects with attributes names in attributes list.

    Raises:
        NotImplementedError: This function is just a wrapper for the subclasses.
    """
    # No cover because is just a wrapper for subclasses.
    raise NotImplementedError  # pragma: no cover

__getitem__(self, attribute_name) special

Get items in a list for a MagicDotPath objects.

Parameters:
  • attribute_name (str) – Names of all attributes.

Returns:
  • BaseMagicDotPath – A MagicDotPath objects with attributes names in attributes list.

Exceptions:
  • NotImplementedError – This function is just a wrapper for the subclasses.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __getitem__(self, attribute_name: str) -> BaseMagicDotPath:
    """
    Get items in a list for a MagicDotPath objects.

    Args:
        attribute_name: Names of all attributes.

    Returns:
        A MagicDotPath objects with attributes names in attributes list.

    Raises:
        NotImplementedError: This function is just a wrapper for the subclasses.
    """
    # No cover because is just a wrapper for subclasses.
    raise NotImplementedError  # pragma: no cover

__gt__(self, other) special

Get a MagicDotPathWithOp objects with a > operator and the correct types.

Types are integer, float, Decimal or BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __gt__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `>` operator and the correct types.

    Types are integer, float, Decimal or BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.GT)

__invert__(self) special

Get a MagicDotPathWithOp objects with a NOT operator.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __invert__(self) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `NOT` operator.

    Returns:
        MagicDotPathWithOp.
    """
    return self._get_one_operand_operator(OperatorType.INVERT)

__le__(self, other) special

Get a MagicDotPathWithOp objects with a <= operator and the correct types.

Types are integer, float, Decimal or BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __le__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `<=` operator and the correct types.

    Types are integer, float, Decimal or BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.LE)

__lt__(self, other) special

Get a MagicDotPathWithOp objects with a < operator and the correct types.

Types are integer, float, Decimal or BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __lt__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `<` operator and the correct types.

    Types are integer, float, Decimal or BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.LT)

__mod__(self, other) special

Get a MagicDotPathWithOp objects with a % operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __mod__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `%` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.MOD)

__mul__(self, other) special

Get a MagicDotPathWithOp objects with a * operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __mul__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `*` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.MUL)

__ne__(self, other) special

Get a MagicDotPathWithOp objects with a <> operator and the correct types.

Types are integer, float, Decimal, string, list, dict, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_generic_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __ne__(  # type: ignore[override]
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `<>` operator and the correct types.

    Types are integer, float, Decimal, string, list, dict, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_generic_operator`
    """
    return self._get_generic_operator(other, OperatorType.NE)

__neg__(self) special

Get a MagicDotPathWithOp objects with a - operator.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __neg__(self) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `-` operator.

    Returns:
        MagicDotPathWithOp.
    """
    return self._get_one_operand_operator(OperatorType.NEG)

__or__(self, other) special

Get a MagicDotPathWithOp objects with a OR operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_generic_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __or__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `OR` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_generic_operator`
    """
    return self._get_generic_operator(other, OperatorType.OR)

__pos__(self) special

Get a MagicDotPathWithOp objects with a + operator.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __pos__(self) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `+` operator.

    Returns:
        MagicDotPathWithOp.
    """
    return self._get_one_operand_operator(OperatorType.POS)

__pow__(self, other) special

Get a MagicDotPathWithOp objects with a ^ operator.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __pow__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `^` operator.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.POW)

__radd__(self, other) special

Get a MagicDotPathWithOp objects with a + operator and the correct types.

This operator is useful when we make 8 + MagicDotPath and not MagicDotPath + 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __radd__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `+` operator and the correct types.

    This operator is useful when we make `8 + MagicDotPath`
    and not `MagicDotPath + 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self.__add__(other)

__rand__(self, other) special

Get a MagicDotPathWithOp objects with a AND operator and the correct types.

This operator is useful when we make 8 & MagicDotPath and not MagicDotPath & 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_generic_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __rand__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `AND` operator and the correct types.

    This operator is useful when we make `8 & MagicDotPath`
    and not `MagicDotPath & 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_generic_operator`
    """
    return self.__and__(other)

__rmod__(self, other) special

Get a MagicDotPathWithOp objects with a % operator and the correct types.

This operator is useful when we make 8 % MagicDotPath and not MagicDotPath % 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __rmod__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `%` operator and the correct types.

    This operator is useful when we make `8 % MagicDotPath`
    and not `MagicDotPath % 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    mdp_with_op = self._get_number_operator(self, OperatorType.MOD)
    mdp_with_op.operand_1 = other
    return mdp_with_op

__rmul__(self, other) special

Get a MagicDotPathWithOp objects with a * operator and the correct types.

This operator is useful when we make 8 * MagicDotPath and not MagicDotPath * 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __rmul__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `*` operator and the correct types.

    This operator is useful when we make `8 * MagicDotPath`
    and not `MagicDotPath * 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self.__mul__(other)

__ror__(self, other) special

Get a MagicDotPathWithOp objects with a OR operator and the correct types.

This operator is useful when we make 8 | MagicDotPath and not MagicDotPath | 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_generic_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __ror__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `OR` operator and the correct types.

    This operator is useful when we make `8 | MagicDotPath`
    and not `MagicDotPath | 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_generic_operator`
    """
    return self.__or__(other)

__rpow__(self, other) special

Get a MagicDotPathWithOp objects with a ^ operator and the correct types.

This operator is useful when we make 8 ^ MagicDotPath and not MagicDotPath ^ 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __rpow__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `^` operator and the correct types.

    This operator is useful when we make `8 ^ MagicDotPath`
    and not `MagicDotPath ^ 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    mdp_with_op = self._get_number_operator(self, OperatorType.POW)
    mdp_with_op.operand_1 = other
    return mdp_with_op

__rsub__(self, other) special

Get a MagicDotPathWithOp objects with a - operator and the correct types.

This operator is useful when we make 8 - MagicDotPath and not MagicDotPath - 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __rsub__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `-` operator and the correct types.

    This operator is useful when we make `8 - MagicDotPath`
    and not `MagicDotPath - 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    mdp_with_op = self._get_number_operator(self, OperatorType.SUB)
    mdp_with_op.operand_1 = other
    return mdp_with_op

__rtruediv__(self, other) special

Get a MagicDotPathWithOp objects with a / operator and the correct types.

This operator is useful when we make 8 / MagicDotPath and not MagicDotPath / 8.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __rtruediv__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `/` operator and the correct types.

    This operator is useful when we make `8 / MagicDotPath`
    and not `MagicDotPath / 8`.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    mdp_with_op = self._get_number_operator(self, OperatorType.TRUEDIV)
    mdp_with_op.operand_1 = other
    return mdp_with_op

__sub__(self, other) special

Get a MagicDotPathWithOp objects with a - operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __sub__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `-` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.SUB)

__truediv__(self, other) special

Get a MagicDotPathWithOp objects with a / operator and the correct types.

Types are integer, float, Decimal, BaseMagicDotPath.

Parameters:
  • other (_VALID_OPERAND_TYPE | BaseMagicDotPath) – The value at which the comparison is made.

Returns:
  • MagicDotPathWithOp – MagicDotPathWithOp.

Exceptions:
  • TypeOperatorError – Indirect raise by _get_number_operator

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __truediv__(
    self,
    other: _VALID_OPERAND_TYPE | BaseMagicDotPath,
) -> MagicDotPathWithOp:
    """
    Get a MagicDotPathWithOp objects with a `/` operator and the correct types.

    Types are integer, float, Decimal, BaseMagicDotPath.

    Args:
        other: The value at which the comparison is made.

    Returns:
        MagicDotPathWithOp.

    Raises:
        TypeOperatorError: Indirect raise by `_get_number_operator`
    """
    return self._get_number_operator(other, OperatorType.TRUEDIV)

col_name(self)

Get the corresponding column name form a MagicDotPath.

Returns:
  • str – A column name with the correct format.

Exceptions:
  • NotImplementedError – This function is just a wrapper for the subclasses.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def col_name(self) -> str:
    """
    Get the corresponding column name form a MagicDotPath.

    Returns:
        A column name with the correct format.

    Raises:
        NotImplementedError: This function is just a wrapper for the subclasses.
    """
    # No cover because is just a wrapper for subclasses.
    raise NotImplementedError  # pragma: no cover

jsonb_path(self, as_str)

Get the corresponding jsonb path from a MagicDotPath.

Parameters:
  • as_str (bool) – Boolean to force the request with json in str.

Returns:
  • str – A path with the correct jsonb syntax.

Exceptions:
  • NotImplementedError – This function is just a wrapper for the subclasses.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def jsonb_path(self, as_str: bool) -> str:
    """
    Get the corresponding jsonb path from a MagicDotPath.

    Args:
        as_str: Boolean to force the request with json in str.

    Returns:
        A path with the correct jsonb syntax.

    Raises:
        NotImplementedError: This function is just a wrapper for the subclasses.
    """
    # No cover because is just a wrapper for subclasses.
    raise NotImplementedError  # pragma: no cover

MagicDotPath

Magical object that can have any attribute.

Inspired by The very useful DotMap module this object allow to write predicate in the lambda function used in SQL clause like .select() or .join(). This is very useful to express SQL constraint.

See the LINQ documentation for more in depth explanation.

Attributes:

Name Type Description
connection Connection

Connection to a db. Useful for safe.

attributes list[str]

Attributes for build the jsonb path.

with_table str | None

Table on which we want to get paths.

column str | None

Column on which we will want to make the request.

Source code in py_linq_sql/utils/classes/magicdotpath.py
@dataclass(eq=False)
class MagicDotPath(BaseMagicDotPath):
    """
    Magical object that can have any attribute.

    Inspired by The very useful [DotMap module](https://github.com/drgrib/dotmap) this
    object allow to write predicate in the lambda function used in SQL clause like
    `.select()` or `.join()`. This is very useful to express SQL constraint.

    See the LINQ documentation for more in depth explanation.

    Attributes:
        connection: Connection to a db. Useful for safe.
        attributes: Attributes for build the jsonb path.
        with_table: Table on which we want to get paths.
        column: Column on which we will want to make the request.

    """

    connection: Connection
    attributes: list[str] = field(default_factory=list)
    with_table: str | None = None
    column: str | None = None

    def __getattr__(self, attribute_name: str) -> MagicDotPath:
        """
        Get attribute in a list for a MagicDotPath objects.

        Args:
            attribute_name: Names of all attributes.

        Returns:
            A MagicDotPath objects with attributes names in attributes list.
        """
        return MagicDotPath(
            self.connection,
            attributes=self.attributes + [f"'{attribute_name}'"],
            with_table=self.with_table,
        )

    def __getitem__(self, attribute_name: str) -> MagicDotPath:
        """
        Get attr from the dict syntax.

        Args:
            attribute_name: Names of all attributes.

        Returns:
            A MagicDotPath objects with attributes names in attributes list.
        """
        return self.__getattr__(attribute_name)

    def safe(self, name: str) -> str:
        """
        Secure a column or a table for a request.

        Args:
            name: Name of the column or table we want to secure.

        Returns:
            Name but verified by psycopg.sql.Identifier.

        Raises:
            psycopg.Error: Indirect raise by `sql.Identifier` or `as_string`.
        """
        return sql.Identifier(name).as_string(self.connection)

    def format_table_with_dot(self) -> str:
        """
        Get the table with dot in good format.

        Returns:
            The table in the good psql format.
        """
        return ".".join(
            [f"{tab}" for tab in self.with_table.split(".")]  # type: ignore[union-attr]
        )

    def jsonb_path(self, as_str: bool) -> str:
        """
        Get the corresponding jsonb path from a MagicDotPath.

        Args:
            as_str: Boolean to force the request with json in str.

        Returns:
            A path with the correct jsonb syntax.

        Raises:
            psycopg.Error: Indirect raise by `safe`.
        """
        self.column = self.safe(self.attributes[0][1:-1])

        res = ""

        if self.with_table:
            table = (
                self.format_table_with_dot()
                if "." in self.with_table
                else f"{self.with_table}"
            )
            res = f"{res}{table}."

        if len(self.attributes) == 1:
            res = f"{res}{self.column}"
        else:
            if as_str:
                path_item = self.attributes[1:-1].copy()
                path_item.insert(0, self.column)
                res = f'{res}{"->".join(path_item)}->>{self.attributes[-1]}'
            else:
                res = f'{res}{self.column}->{"->".join(self.attributes[1:])}'
        return res

    def col_name(self) -> str:
        """
        Get the corresponding column name form a MagicDotPath.

        Returns:
            A column name with the correct format.
        """
        result = []

        if self.with_table:
            table = (
                self.format_table_with_dot()
                if "." in self.with_table
                else self.with_table
            )
            result.append(table[1:-1])

        for att in self.attributes:
            result.append(att[1:-1])

        return "_".join(result)

__getattr__(self, attribute_name) special

Get attribute in a list for a MagicDotPath objects.

Parameters:
  • attribute_name (str) – Names of all attributes.

Returns:
  • MagicDotPath – A MagicDotPath objects with attributes names in attributes list.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __getattr__(self, attribute_name: str) -> MagicDotPath:
    """
    Get attribute in a list for a MagicDotPath objects.

    Args:
        attribute_name: Names of all attributes.

    Returns:
        A MagicDotPath objects with attributes names in attributes list.
    """
    return MagicDotPath(
        self.connection,
        attributes=self.attributes + [f"'{attribute_name}'"],
        with_table=self.with_table,
    )

__getitem__(self, attribute_name) special

Get attr from the dict syntax.

Parameters:
  • attribute_name (str) – Names of all attributes.

Returns:
  • MagicDotPath – A MagicDotPath objects with attributes names in attributes list.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def __getitem__(self, attribute_name: str) -> MagicDotPath:
    """
    Get attr from the dict syntax.

    Args:
        attribute_name: Names of all attributes.

    Returns:
        A MagicDotPath objects with attributes names in attributes list.
    """
    return self.__getattr__(attribute_name)

col_name(self)

Get the corresponding column name form a MagicDotPath.

Returns:
  • str – A column name with the correct format.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def col_name(self) -> str:
    """
    Get the corresponding column name form a MagicDotPath.

    Returns:
        A column name with the correct format.
    """
    result = []

    if self.with_table:
        table = (
            self.format_table_with_dot()
            if "." in self.with_table
            else self.with_table
        )
        result.append(table[1:-1])

    for att in self.attributes:
        result.append(att[1:-1])

    return "_".join(result)

format_table_with_dot(self)

Get the table with dot in good format.

Returns:
  • str – The table in the good psql format.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def format_table_with_dot(self) -> str:
    """
    Get the table with dot in good format.

    Returns:
        The table in the good psql format.
    """
    return ".".join(
        [f"{tab}" for tab in self.with_table.split(".")]  # type: ignore[union-attr]
    )

jsonb_path(self, as_str)

Get the corresponding jsonb path from a MagicDotPath.

Parameters:
  • as_str (bool) – Boolean to force the request with json in str.

Returns:
  • str – A path with the correct jsonb syntax.

Exceptions:
  • psycopg.Error – Indirect raise by safe.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def jsonb_path(self, as_str: bool) -> str:
    """
    Get the corresponding jsonb path from a MagicDotPath.

    Args:
        as_str: Boolean to force the request with json in str.

    Returns:
        A path with the correct jsonb syntax.

    Raises:
        psycopg.Error: Indirect raise by `safe`.
    """
    self.column = self.safe(self.attributes[0][1:-1])

    res = ""

    if self.with_table:
        table = (
            self.format_table_with_dot()
            if "." in self.with_table
            else f"{self.with_table}"
        )
        res = f"{res}{table}."

    if len(self.attributes) == 1:
        res = f"{res}{self.column}"
    else:
        if as_str:
            path_item = self.attributes[1:-1].copy()
            path_item.insert(0, self.column)
            res = f'{res}{"->".join(path_item)}->>{self.attributes[-1]}'
        else:
            res = f'{res}{self.column}->{"->".join(self.attributes[1:])}'
    return res

safe(self, name)

Secure a column or a table for a request.

Parameters:
  • name (str) – Name of the column or table we want to secure.

Returns:
  • str – Name but verified by psycopg.sql.Identifier.

Exceptions:
  • psycopg.Error – Indirect raise by sql.Identifier or as_string.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def safe(self, name: str) -> str:
    """
    Secure a column or a table for a request.

    Args:
        name: Name of the column or table we want to secure.

    Returns:
        Name but verified by psycopg.sql.Identifier.

    Raises:
        psycopg.Error: Indirect raise by `sql.Identifier` or `as_string`.
    """
    return sql.Identifier(name).as_string(self.connection)

MagicDotPathWithOp

Magical object that can have any attribute and can be subject to many comparison.

This class inherited from MagicDotPath.

Inspired by The very useful DotMap module this object allow to write predicate in the lambda function used in SQL clause like .select() or .join(). This is very useful to express SQL constraint.

See the LINQ documentation for more in depth explanation.

Attributes:

Name Type Description
operand_1 py_linq_sql.utils.classes.magicdotpath.BaseMagicDotPath | float | int | str | list | dict | decimal.Decimal | bool

First operand for the operation.

operand_2 py_linq_sql.utils.classes.magicdotpath.BaseMagicDotPath | float | int | str | list | dict | decimal.Decimal | bool | None

Second operand for the operation.

operator py_linq_sql.utils.classes.op_and_func_of_mdp.HyperBFuncType | py_linq_sql.utils.classes.op_and_func_of_mdp.MathFunctType | py_linq_sql.utils.classes.op_and_func_of_mdp.OperatorType | py_linq_sql.utils.classes.op_and_func_of_mdp.TrigoFunctType | py_linq_sql.utils.classes.op_and_func_of_mdp.StrFunctType

Operator for comparison.

my_type Type[Any]

Type of other.

Source code in py_linq_sql/utils/classes/magicdotpath.py
@dataclass(eq=False)
class MagicDotPathWithOp(BaseMagicDotPath):
    """
    Magical object that can have any attribute and can be subject to many comparison.

    This class inherited from MagicDotPath.

    Inspired by The very useful [DotMap module](https://github.com/drgrib/dotmap) this
    object allow to write predicate in the lambda function used in SQL clause like
    `.select()` or `.join()`. This is very useful to express SQL constraint.

    See the LINQ documentation for more in depth explanation.

    Attributes:
        operand_1: First operand for the operation.
        operand_2: Second operand for the operation.
        operator: Operator for comparison.
        my_type: Type of other.

    """

    operand_1: BaseMagicDotPath | _VALID_OPERAND_TYPE
    operator: _OPERATORTYPE
    operand_2: BaseMagicDotPath | _VALID_OPERAND_TYPE | None
    my_type: Type[Any]

    def jsonb_path(self, as_str: bool) -> str:
        """
        Get the corresponding jsonb path from a MagicDotPathWithOp.

        Args:
            as_str: Boolean to force the request with json in str.

        Returns:
            A path with the correct jsonb syntax.

        Raises:
            psycopg.Error: Indirect raise by `MagicDotPath.safe`.
            TypeOperatorError: Indirect raise by `json_path_hyper`, `json_path_math`,
                `json_path_ope` or `json_path_trigo`.
        """
        as_str = self.my_type == str

        path_op = DotMap()

        match self.operand_1:
            case MagicDotPath() | MagicDotPathWithOp():
                path_op.op1 = self.operand_1.jsonb_path(as_str)
            case _:
                path_op.op1 = str(self.operand_1)

        match self.operand_2:
            case MagicDotPath() | MagicDotPathWithOp():
                path_op.op2 = self.operand_2.jsonb_path(as_str)
            case dict():
                operand_2_in_good_format = json.dumps(self.operand_2)
                path_op.op2 = f"'{operand_2_in_good_format}'::jsonb"
            case list():
                if self.operator in [OperatorType.IN]:
                    path_op.op2 = (
                        f"""({", ".join([f"'{val}'" for val in self.operand_2])})"""
                    )
                else:
                    path_op.op2 = f"'{self.operand_2}'::jsonb"
            case _:
                path_op.op2 = str(self.operand_2)

        match self.my_type:
            case type() if self.my_type == bool:
                result = (
                    f"CAST({path_op.op1} AS boolean) {self.operator.psql} {path_op.op2}"
                )
            case type() if self.operator in [
                OperatorType.AND,
                OperatorType.OR,
                OperatorType.INVERT,
                OperatorType.ABS,
                OperatorType.POS,
                OperatorType.NEG,
                OperatorType.IN,
            ]:
                result = json_path_ope(path_op, self.operator)
            case type() if isinstance(self.operator, HyperBFuncType):
                result = json_path_hyper(path_op, self.operator)
            case type() if isinstance(self.operator, MathFunctType):
                result = json_path_math(path_op, self.operator)
            case type() if isinstance(self.operator, TrigoFunctType):
                result = json_path_trigo(path_op, self.operator)
            case type() if isinstance(self.operator, StrFunctType):
                result = json_path_str(path_op, self.operator)
            case type() if self.my_type == BaseMagicDotPath:
                result = (
                    f"CAST({path_op.op1} AS decimal) "
                    f"{self.operator.psql} "
                    f"CAST({path_op.op2} AS decimal)"
                )
            case type() if self.my_type in (int, float, Decimal):
                result = (
                    f"CAST({path_op.op1} AS decimal) {self.operator.psql} {path_op.op2}"
                )
            case type() if self.my_type == str:
                result = f"{path_op.op1} {self.operator.psql} '{path_op.op2}'"
            case _:
                result = f"{path_op.op1} {self.operator.psql} {path_op.op2}"

        return result

    def col_name(self) -> str:
        """
        Get the corresponding column name form a MagicDotPath.

        Returns:
            A column name with the correct format.

        Raises:
            TypeOperatorError: Indirect raise by `col_name_hyper`, `col_name_math`,
                `col_name_ope` or `col_name_trigo`.
        """
        name_op = DotMap()

        match self.operand_1:
            case BaseMagicDotPath():
                name_op.op1 = self.operand_1.col_name()
            case _:
                name_op.op1 = str(self.operand_1)

        match self.operand_2:
            case None:
                name_op.op2 = None
            case BaseMagicDotPath():
                name_op.op2 = self.operand_2.col_name()
            case float() | int() | Decimal():
                name_op.op2 = _clean_number_str(str(self.operand_2))
            # TODO: test this
            case list():
                name_op.op2 = f"""({','.join([str(val) for val in self.operand_2])})"""

        operator = self.operator
        match operator:
            case operator if operator in HyperBFuncType:
                result = col_name_hyper(name_op, operator)
            case operator if operator in MathFunctType:
                result = col_name_math(name_op, operator)
            case operator if operator in OperatorType:
                result = col_name_ope(name_op, operator)
            case operator if operator in TrigoFunctType:
                result = col_name_trigo(name_op, operator)
            case operator if operator in StrFunctType:
                result = col_name_str(name_op, operator)
            # No cover because is just an other security,
            # but we can't go in this case thanks to Enum.
            case _:  # pragma: no cover
                result = f"{name_op.op1}_???_{name_op.op2}"

        return f"{result}"

col_name(self)

Get the corresponding column name form a MagicDotPath.

Returns:
  • str – A column name with the correct format.

Exceptions:
  • TypeOperatorError – Indirect raise by col_name_hyper, col_name_math, col_name_ope or col_name_trigo.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def col_name(self) -> str:
    """
    Get the corresponding column name form a MagicDotPath.

    Returns:
        A column name with the correct format.

    Raises:
        TypeOperatorError: Indirect raise by `col_name_hyper`, `col_name_math`,
            `col_name_ope` or `col_name_trigo`.
    """
    name_op = DotMap()

    match self.operand_1:
        case BaseMagicDotPath():
            name_op.op1 = self.operand_1.col_name()
        case _:
            name_op.op1 = str(self.operand_1)

    match self.operand_2:
        case None:
            name_op.op2 = None
        case BaseMagicDotPath():
            name_op.op2 = self.operand_2.col_name()
        case float() | int() | Decimal():
            name_op.op2 = _clean_number_str(str(self.operand_2))
        # TODO: test this
        case list():
            name_op.op2 = f"""({','.join([str(val) for val in self.operand_2])})"""

    operator = self.operator
    match operator:
        case operator if operator in HyperBFuncType:
            result = col_name_hyper(name_op, operator)
        case operator if operator in MathFunctType:
            result = col_name_math(name_op, operator)
        case operator if operator in OperatorType:
            result = col_name_ope(name_op, operator)
        case operator if operator in TrigoFunctType:
            result = col_name_trigo(name_op, operator)
        case operator if operator in StrFunctType:
            result = col_name_str(name_op, operator)
        # No cover because is just an other security,
        # but we can't go in this case thanks to Enum.
        case _:  # pragma: no cover
            result = f"{name_op.op1}_???_{name_op.op2}"

    return f"{result}"

jsonb_path(self, as_str)

Get the corresponding jsonb path from a MagicDotPathWithOp.

Parameters:
  • as_str (bool) – Boolean to force the request with json in str.

Returns:
  • str – A path with the correct jsonb syntax.

Exceptions:
  • psycopg.Error – Indirect raise by MagicDotPath.safe.

  • TypeOperatorError – Indirect raise by json_path_hyper, json_path_math, json_path_ope or json_path_trigo.

Source code in py_linq_sql/utils/classes/magicdotpath.py
def jsonb_path(self, as_str: bool) -> str:
    """
    Get the corresponding jsonb path from a MagicDotPathWithOp.

    Args:
        as_str: Boolean to force the request with json in str.

    Returns:
        A path with the correct jsonb syntax.

    Raises:
        psycopg.Error: Indirect raise by `MagicDotPath.safe`.
        TypeOperatorError: Indirect raise by `json_path_hyper`, `json_path_math`,
            `json_path_ope` or `json_path_trigo`.
    """
    as_str = self.my_type == str

    path_op = DotMap()

    match self.operand_1:
        case MagicDotPath() | MagicDotPathWithOp():
            path_op.op1 = self.operand_1.jsonb_path(as_str)
        case _:
            path_op.op1 = str(self.operand_1)

    match self.operand_2:
        case MagicDotPath() | MagicDotPathWithOp():
            path_op.op2 = self.operand_2.jsonb_path(as_str)
        case dict():
            operand_2_in_good_format = json.dumps(self.operand_2)
            path_op.op2 = f"'{operand_2_in_good_format}'::jsonb"
        case list():
            if self.operator in [OperatorType.IN]:
                path_op.op2 = (
                    f"""({", ".join([f"'{val}'" for val in self.operand_2])})"""
                )
            else:
                path_op.op2 = f"'{self.operand_2}'::jsonb"
        case _:
            path_op.op2 = str(self.operand_2)

    match self.my_type:
        case type() if self.my_type == bool:
            result = (
                f"CAST({path_op.op1} AS boolean) {self.operator.psql} {path_op.op2}"
            )
        case type() if self.operator in [
            OperatorType.AND,
            OperatorType.OR,
            OperatorType.INVERT,
            OperatorType.ABS,
            OperatorType.POS,
            OperatorType.NEG,
            OperatorType.IN,
        ]:
            result = json_path_ope(path_op, self.operator)
        case type() if isinstance(self.operator, HyperBFuncType):
            result = json_path_hyper(path_op, self.operator)
        case type() if isinstance(self.operator, MathFunctType):
            result = json_path_math(path_op, self.operator)
        case type() if isinstance(self.operator, TrigoFunctType):
            result = json_path_trigo(path_op, self.operator)
        case type() if isinstance(self.operator, StrFunctType):
            result = json_path_str(path_op, self.operator)
        case type() if self.my_type == BaseMagicDotPath:
            result = (
                f"CAST({path_op.op1} AS decimal) "
                f"{self.operator.psql} "
                f"CAST({path_op.op2} AS decimal)"
            )
        case type() if self.my_type in (int, float, Decimal):
            result = (
                f"CAST({path_op.op1} AS decimal) {self.operator.psql} {path_op.op2}"
            )
        case type() if self.my_type == str:
            result = f"{path_op.op1} {self.operator.psql} '{path_op.op2}'"
        case _:
            result = f"{path_op.op1} {self.operator.psql} {path_op.op2}"

    return result

MagicDotPathAggregate

MagicDotPath for aggregation.

Attributes:

Name Type Description
mdp MagicDotPath

A MagicDotPath.

operand py_linq_sql.utils.classes.magicdotpath.AggregateType | str

Aggregation type.

separator str | None

Separator for string_agg aggregate. In other case its None.

Source code in py_linq_sql/utils/classes/magicdotpath.py
@dataclass
class MagicDotPathAggregate:
    """
    MagicDotPath for aggregation.

    Attributes:
        mdp: A MagicDotPath.
        operand: Aggregation type.
        separator: Separator for string_agg aggregate. In other case its None.

    """

    mdp: MagicDotPath
    operand: AggregateType | str  # HACK: It's just the time that mypy supports the
    # Strenum. https://github.com/python/mypy/issues
    cast_type: type
    separator: str | None = None