Queryset mixins (#629)

* add enum field

* add decorator for asyncio

* fix enum typing, additional tests, add docs

* add more tests

* query-mixin

* use dict to replace ordereddict

Co-authored-by: collerek <collerek@gmail.com>
This commit is contained in:
Ethon
2022-05-07 20:02:30 +08:00
committed by GitHub
parent 11bf6d30c4
commit 6e2a2ad129
13 changed files with 33 additions and 25 deletions

View File

@ -1,4 +1,3 @@
import collections
import itertools
import sqlite3
from typing import Any, Dict, List, TYPE_CHECKING, Tuple, Type
@ -145,7 +144,7 @@ def extract_annotations_and_default_vals(attrs: Dict) -> Tuple[Dict, Dict]:
return attrs, model_fields
def group_related_list(list_: List) -> collections.OrderedDict:
def group_related_list(list_: List) -> Dict:
"""
Translates the list of related strings into a dictionary.
That way nested models are grouped to traverse them in a right order
@ -174,9 +173,7 @@ def group_related_list(list_: List) -> collections.OrderedDict:
result_dict[key] = group_related_list(new)
else:
result_dict.setdefault(key, []).extend(new)
return collections.OrderedDict(
sorted(result_dict.items(), key=lambda item: len(item[1]))
)
return dict(sorted(result_dict.items(), key=lambda item: len(item[1])))
def meta_field_not_set(model: Type["Model"], field_name: str) -> bool:

View File

@ -1,4 +1,3 @@
from collections import OrderedDict
from typing import Dict, List, Optional, TYPE_CHECKING, cast
import ormar
@ -32,7 +31,7 @@ class MergeModelMixin:
:rtype: List["Model"]
"""
merged_rows: List["Model"] = []
grouped_instances: OrderedDict = OrderedDict()
grouped_instances: Dict = {}
for model in result_rows:
grouped_instances.setdefault(model.pk, []).append(model)

View File

@ -4,10 +4,10 @@ Contains QuerySet and different Query classes to allow for constructing of sql q
from ormar.queryset.actions import FilterAction, OrderAction, SelectAction
from ormar.queryset.clause import and_, or_
from ormar.queryset.field_accessor import FieldAccessor
from ormar.queryset.filter_query import FilterQuery
from ormar.queryset.limit_query import LimitQuery
from ormar.queryset.offset_query import OffsetQuery
from ormar.queryset.order_query import OrderQuery
from ormar.queryset.queries import FilterQuery
from ormar.queryset.queries import LimitQuery
from ormar.queryset.queries import OffsetQuery
from ormar.queryset.queries import OrderQuery
from ormar.queryset.queryset import QuerySet
__all__ = [

View File

@ -1,4 +1,3 @@
from collections import OrderedDict
from typing import Any, Dict, List, Optional, TYPE_CHECKING, Tuple, Type, cast
import sqlalchemy
@ -22,7 +21,7 @@ class SqlJoin:
columns: List[sqlalchemy.Column],
excludable: "ExcludableItems",
order_columns: Optional[List["OrderAction"]],
sorted_orders: OrderedDict,
sorted_orders: Dict,
main_model: Type["Model"],
relation_name: str,
relation_str: str,
@ -118,7 +117,7 @@ class SqlJoin:
return text(f"{left_part}={right_part}")
def build_join(self) -> Tuple[List, sqlalchemy.sql.select, List, OrderedDict]:
def build_join(self) -> Tuple[List, sqlalchemy.sql.select, List, Dict]:
"""
Main external access point for building a join.
Splits the join definition, updates fields and exclude_fields if needed,
@ -126,7 +125,7 @@ class SqlJoin:
used_aliases and sort_orders.
:return: list of used aliases, select from, list of aliased columns, sort orders
:rtype: Tuple[List[str], Join, List[TextClause], collections.OrderedDict]
:rtype: Tuple[List[str], Join, List[TextClause], Dict]
"""
if self.target_field.is_multi:
self._process_m2m_through_table()

View File

@ -0,0 +1,15 @@
from ormar.queryset.queries.filter_query import FilterQuery
from ormar.queryset.queries.limit_query import LimitQuery
from ormar.queryset.queries.offset_query import OffsetQuery
from ormar.queryset.queries.order_query import OrderQuery
from ormar.queryset.queries.prefetch_query import PrefetchQuery
from ormar.queryset.queries.query import Query
__all__ = [
"FilterQuery",
"LimitQuery",
"OffsetQuery",
"OrderQuery",
"PrefetchQuery",
"Query",
]

View File

@ -2,7 +2,7 @@ from typing import Dict, List, Sequence, Set, TYPE_CHECKING, Tuple, Type, cast
import ormar
from ormar.queryset.clause import QueryClause
from ormar.queryset.query import Query
from ormar.queryset.queries.query import Query
from ormar.queryset.utils import extract_models_to_dict_of_lists, translate_list_to_dict
if TYPE_CHECKING: # pragma: no cover

View File

@ -1,5 +1,4 @@
from collections import OrderedDict
from typing import List, Optional, TYPE_CHECKING, Tuple, Type, Union
from typing import Dict, List, Optional, TYPE_CHECKING, Tuple, Type, Union
import sqlalchemy
from sqlalchemy import Table, text
@ -7,7 +6,7 @@ from sqlalchemy.sql import Join
import ormar # noqa I100
from ormar.models.helpers.models import group_related_list
from ormar.queryset import FilterQuery, LimitQuery, OffsetQuery, OrderQuery
from ormar.queryset.queries import FilterQuery, LimitQuery, OffsetQuery, OrderQuery
from ormar.queryset.actions.filter_action import FilterAction
from ormar.queryset.join import SqlJoin
@ -45,7 +44,7 @@ class Query:
self.select_from: Union[Join, Table, List[str]] = []
self.columns = [sqlalchemy.Column]
self.order_columns = order_bys
self.sorted_orders: OrderedDict[OrderAction, text] = OrderedDict()
self.sorted_orders: Dict[OrderAction, text] = {}
self._init_sorted_orders()
self.limit_raw_sql = limit_raw_sql
@ -183,7 +182,7 @@ class Query:
pk_alias = self.model_cls.get_column_alias(self.model_cls.Meta.pkname)
pk_aliased_name = f"{self.table.name}.{pk_alias}"
qry_text = sqlalchemy.text(f"{pk_aliased_name}")
maxes = OrderedDict()
maxes = {}
for order in list(self.sorted_orders.keys()):
if order is not None and order.get_field_name_text() != pk_aliased_name:
aliased_col = order.get_field_name_text()

View File

@ -37,8 +37,8 @@ from ormar.exceptions import (
from ormar.queryset import FieldAccessor, FilterQuery, SelectAction
from ormar.queryset.actions.order_action import OrderAction
from ormar.queryset.clause import FilterGroup, QueryClause
from ormar.queryset.prefetch_query import PrefetchQuery
from ormar.queryset.query import Query
from ormar.queryset.queries.prefetch_query import PrefetchQuery
from ormar.queryset.queries.query import Query
from ormar.queryset.reverse_alias_resolver import ReverseAliasResolver
if TYPE_CHECKING: # pragma no cover

View File

@ -2,8 +2,7 @@ import databases
import sqlalchemy
import ormar
from ormar.models.mixins import ExcludableMixin
from ormar.queryset.prefetch_query import sort_models
from ormar.queryset.queries.prefetch_query import sort_models
from ormar.queryset.utils import (
subtract_dict,
translate_list_to_dict,