Coverage for pyodmongo/models/db_field_info.py: 100%
46 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-03-27 14:31 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-03-27 14:31 +0000
1from typing import Any
2from dataclasses import dataclass
3from .query_operators import ComparisonOperator
4from .id_model import Id
5from .db_decimal import DbDecimal
6from bson import ObjectId
7from decimal import Decimal
8from bson import Decimal128
9from ..services.verify_subclasses import is_subclass
12@dataclass
13class DbField:
14 """
15 Represents a field within a database model, containing metadata necessary for
16 managing the serialization and deserialization of model fields, especially in
17 contexts involving references to other documents or complex nested structures.
19 Attributes:
20 field_name (str | None): The name of the field as defined in the database model.
21 field_alias (str | None): The alias used for the field in database operations,
22 which might differ from the field name.
23 path_str (str | None): The string representation of the path to the field within
24 nested structures or related models.
25 field_type (Any | None): The data type of the field, which can be any valid Python
26 type or a more complex custom type.
27 by_reference (bool | None): Indicates whether the field is linked by reference
28 to another document or model, rather than embedded.
29 is_list (bool | None): Specifies if the field is expected to be a list of items,
30 typically used for handling multiple relationships or
31 collections of values.
32 has_model_fields (bool | None): Indicates if the field itself contains sub-fields
33 that are also modeled, suggesting a nested data
34 structure that requires special handling.
35 """
37 field_name: str = None
38 field_alias: str = None
39 path_str: str = None
40 field_type: Any = None
41 by_reference: bool = None
42 is_list: bool = None
43 has_model_fields: bool = None
45 def comparison_operator(self, operator: str, value: Any) -> ComparisonOperator:
46 type_of_value = type(value)
47 if self.by_reference or self.field_type == Id:
48 if type_of_value != list and value is not None:
49 value = ObjectId(value)
50 elif type_of_value == list:
51 value = [ObjectId(v) for v in value]
53 elif (
54 self.field_type == Decimal or self.field_type == DbDecimal
55 ) and value is not None:
56 if type_of_value == list:
57 value = [Decimal128(str(o)) for o in value]
58 else:
59 value = Decimal128(str(value))
61 return ComparisonOperator(
62 path_str=self.path_str, operator=operator, value=value
63 )
65 def __lt__(self, value: Any) -> ComparisonOperator:
66 return self.comparison_operator(operator="$lt", value=value)
68 def __le__(self, value: Any) -> ComparisonOperator:
69 return self.comparison_operator(operator="$lte", value=value)
71 def __eq__(self, value: Any) -> ComparisonOperator:
72 if isinstance(value, DbField):
73 return super().__eq__(value)
74 return self.comparison_operator(operator="$eq", value=value)
76 def __ne__(self, value: Any) -> ComparisonOperator:
77 if isinstance(value, DbField):
78 return super().__ne__(value)
79 return self.comparison_operator(operator="$ne", value=value)
81 def __gt__(self, value: Any) -> ComparisonOperator:
82 return self.comparison_operator(operator="$gt", value=value)
84 def __ge__(self, value: Any) -> ComparisonOperator:
85 return self.comparison_operator(operator="$gte", value=value)