diff --git a/.coverage b/.coverage index e405d35..52f8587 100644 Binary files a/.coverage and b/.coverage differ diff --git a/ormar/queryset/__init__.py b/ormar/queryset/__init__.py index 7bf6fc6..2bc0a6d 100644 --- a/ormar/queryset/__init__.py +++ b/ormar/queryset/__init__.py @@ -1,3 +1,7 @@ +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.queryset import QuerySet -__all__ = ["QuerySet"] +__all__ = ["QuerySet", "FilterQuery", "LimitQuery", "OffsetQuery", "OrderQuery"] diff --git a/ormar/queryset/filter_query.py b/ormar/queryset/filter_query.py new file mode 100644 index 0000000..8db8185 --- /dev/null +++ b/ormar/queryset/filter_query.py @@ -0,0 +1,17 @@ +from typing import List + +import sqlalchemy + + +class FilterQuery: + def __init__(self, filter_clauses: List) -> None: + self.filter_clauses = filter_clauses + + def apply(self, expr: sqlalchemy.sql.select) -> sqlalchemy.sql.select: + if self.filter_clauses: + if len(self.filter_clauses) == 1: + clause = self.filter_clauses[0] + else: + clause = sqlalchemy.sql.and_(*self.filter_clauses) + expr = expr.where(clause) + return expr diff --git a/ormar/queryset/limit_query.py b/ormar/queryset/limit_query.py new file mode 100644 index 0000000..2de7950 --- /dev/null +++ b/ormar/queryset/limit_query.py @@ -0,0 +1,11 @@ +import sqlalchemy + + +class LimitQuery: + def __init__(self, limit_count: int) -> None: + self.limit_count = limit_count + + def apply(self, expr: sqlalchemy.sql.select) -> sqlalchemy.sql.select: + if self.limit_count: + expr = expr.limit(self.limit_count) + return expr diff --git a/ormar/queryset/offset_query.py b/ormar/queryset/offset_query.py new file mode 100644 index 0000000..bca365b --- /dev/null +++ b/ormar/queryset/offset_query.py @@ -0,0 +1,11 @@ +import sqlalchemy + + +class OffsetQuery: + def __init__(self, query_offset: int) -> None: + self.query_offset = query_offset + + def apply(self, expr: sqlalchemy.sql.select) -> sqlalchemy.sql.select: + if self.query_offset: + expr = expr.offset(self.query_offset) + return expr diff --git a/ormar/queryset/order_query.py b/ormar/queryset/order_query.py new file mode 100644 index 0000000..cbb4a81 --- /dev/null +++ b/ormar/queryset/order_query.py @@ -0,0 +1,14 @@ +from typing import List + +import sqlalchemy + + +class OrderQuery: + def __init__(self, order_bys: List) -> None: + self.order_bys = order_bys + + def apply(self, expr: sqlalchemy.sql.select) -> sqlalchemy.sql.select: + if self.order_bys: + for order in self.order_bys: + expr = expr.order_by(order) + return expr diff --git a/ormar/queryset/query.py b/ormar/queryset/query.py index 5cb507c..b1e8830 100644 --- a/ormar/queryset/query.py +++ b/ormar/queryset/query.py @@ -7,6 +7,7 @@ import ormar # noqa I100 from ormar.fields import BaseField from ormar.fields.foreign_key import ForeignKeyField from ormar.fields.many_to_many import ManyToManyField +from ormar.queryset import FilterQuery, LimitQuery, OffsetQuery, OrderQuery from ormar.relations.alias_manager import AliasManager if TYPE_CHECKING: # pragma no cover @@ -170,27 +171,13 @@ class Query: from_key = part return to_key, from_key - def filter(self, expr: sqlalchemy.sql.select) -> sqlalchemy.sql.select: # noqa A003 - if self.filter_clauses: - if len(self.filter_clauses) == 1: - clause = self.filter_clauses[0] - else: - clause = sqlalchemy.sql.and_(*self.filter_clauses) - expr = expr.where(clause) - return expr - def _apply_expression_modifiers( self, expr: sqlalchemy.sql.select ) -> sqlalchemy.sql.select: - expr = self.filter(expr) - if self.limit_count: - expr = expr.limit(self.limit_count) - - if self.query_offset: - expr = expr.offset(self.query_offset) - - for order in self.order_bys: - expr = expr.order_by(order) + expr = FilterQuery(filter_clauses=self.filter_clauses).apply(expr) + expr = LimitQuery(limit_count=self.limit_count).apply(expr) + expr = OffsetQuery(query_offset=self.query_offset).apply(expr) + expr = OrderQuery(order_bys=self.order_bys).apply(expr) return expr def _reset_query_parameters(self) -> None: diff --git a/ormar/queryset/queryset.py b/ormar/queryset/queryset.py index a4c48d3..79f9ff2 100644 --- a/ormar/queryset/queryset.py +++ b/ormar/queryset/queryset.py @@ -5,9 +5,11 @@ import sqlalchemy import ormar # noqa I100 from ormar import MultipleMatches, NoMatch +from ormar.queryset import FilterQuery from ormar.queryset.clause import QueryClause from ormar.queryset.query import Query + if TYPE_CHECKING: # pragma no cover from ormar import Model @@ -119,14 +121,9 @@ class QuerySet: async def delete(self, **kwargs: Any) -> int: if kwargs: return await self.filter(**kwargs).delete() - qry = Query( - model_cls=self.model_cls, - select_related=self._select_related, - filter_clauses=self.filter_clauses, - offset=self.query_offset, - limit_count=self.limit_count, + expr = FilterQuery(filter_clauses=self.filter_clauses,).apply( + self.table.delete() ) - expr = qry.filter(self.table.delete()) return await self.database.execute(expr) def limit(self, limit_count: int) -> "QuerySet":