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: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
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: |
|
---|
Returns: |
|
---|
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: |
|
---|
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: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Exceptions: |
|
---|
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: |
|
---|
Returns: |
|
---|
Exceptions: |
|
---|
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