summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/query.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/orm/query.py')
-rw-r--r--lib/sqlalchemy/orm/query.py51
1 files changed, 34 insertions, 17 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 15259f130..61174487a 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -21,7 +21,12 @@ database to return iterable result sets.
import collections.abc as collections_abc
import itertools
import operator
-import typing
+from typing import Any
+from typing import Generic
+from typing import Iterable
+from typing import List
+from typing import Optional
+from typing import TypeVar
from . import exc as orm_exc
from . import interfaces
@@ -35,8 +40,9 @@ from .context import LABEL_STYLE_LEGACY_ORM
from .context import ORMCompileState
from .context import ORMFromStatementCompileState
from .context import QueryContext
+from .interfaces import ORMColumnDescription
from .interfaces import ORMColumnsClauseRole
-from .util import aliased
+from .util import AliasedClass
from .util import object_mapper
from .util import with_parent
from .. import exc as sa_exc
@@ -45,16 +51,19 @@ from .. import inspection
from .. import log
from .. import sql
from .. import util
+from ..engine import Result
from ..sql import coercions
from ..sql import expression
from ..sql import roles
from ..sql import Select
from ..sql import util as sql_util
from ..sql import visitors
+from ..sql._typing import _FromClauseElement
from ..sql.annotation import SupportsCloneAnnotations
from ..sql.base import _entity_namespace_key
from ..sql.base import _generative
from ..sql.base import Executable
+from ..sql.expression import Exists
from ..sql.selectable import _MemoizedSelectEntities
from ..sql.selectable import _SelectFromElements
from ..sql.selectable import ForUpdateArg
@@ -67,9 +76,12 @@ from ..sql.selectable import SelectBase
from ..sql.selectable import SelectStatementGrouping
from ..sql.visitors import InternalTraversal
-__all__ = ["Query", "QueryContext", "aliased"]
-SelfQuery = typing.TypeVar("SelfQuery", bound="Query")
+__all__ = ["Query", "QueryContext"]
+
+_T = TypeVar("_T", bound=Any)
+
+SelfQuery = TypeVar("SelfQuery", bound="Query")
@inspection._self_inspects
@@ -80,7 +92,9 @@ class Query(
HasPrefixes,
HasSuffixes,
HasHints,
+ log.Identified,
Executable,
+ Generic[_T],
):
"""ORM-level SQL construction object.
@@ -1040,7 +1054,7 @@ class Query(
for prop in mapper.iterate_properties:
if (
- isinstance(prop, relationships.RelationshipProperty)
+ isinstance(prop, relationships.Relationship)
and prop.mapper is entity_zero.mapper
):
property = prop # noqa
@@ -1064,7 +1078,7 @@ class Query(
if alias is not None:
# TODO: deprecate
- entity = aliased(entity, alias)
+ entity = AliasedClass(entity, alias)
self._raw_columns = list(self._raw_columns)
@@ -1992,7 +2006,9 @@ class Query(
@_generative
@_assertions(_no_clauseelement_condition)
- def select_from(self: SelfQuery, *from_obj) -> SelfQuery:
+ def select_from(
+ self: SelfQuery, *from_obj: _FromClauseElement
+ ) -> SelfQuery:
r"""Set the FROM clause of this :class:`.Query` explicitly.
:meth:`.Query.select_from` is often used in conjunction with
@@ -2144,7 +2160,7 @@ class Query(
self._distinct = True
return self
- def all(self):
+ def all(self) -> List[_T]:
"""Return the results represented by this :class:`_query.Query`
as a list.
@@ -2183,7 +2199,7 @@ class Query(
self._statement = statement
return self
- def first(self):
+ def first(self) -> Optional[_T]:
"""Return the first result of this ``Query`` or
None if the result doesn't contain any row.
@@ -2209,7 +2225,7 @@ class Query(
else:
return self.limit(1)._iter().first()
- def one_or_none(self):
+ def one_or_none(self) -> Optional[_T]:
"""Return at most one result or raise an exception.
Returns ``None`` if the query selects
@@ -2235,7 +2251,7 @@ class Query(
"""
return self._iter().one_or_none()
- def one(self):
+ def one(self) -> _T:
"""Return exactly one result or raise an exception.
Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
@@ -2255,7 +2271,7 @@ class Query(
"""
return self._iter().one()
- def scalar(self):
+ def scalar(self) -> Any:
"""Return the first element of the first result or None
if no rows present. If multiple rows are returned,
raises MultipleResultsFound.
@@ -2283,7 +2299,7 @@ class Query(
except orm_exc.NoResultFound:
return None
- def __iter__(self):
+ def __iter__(self) -> Iterable[_T]:
return self._iter().__iter__()
def _iter(self):
@@ -2309,7 +2325,7 @@ class Query(
return result
- def __str__(self):
+ def __str__(self) -> str:
statement = self._statement_20()
try:
@@ -2327,7 +2343,7 @@ class Query(
return fn(clause=statement, **kw)
@property
- def column_descriptions(self):
+ def column_descriptions(self) -> List[ORMColumnDescription]:
"""Return metadata about the columns which would be
returned by this :class:`_query.Query`.
@@ -2368,7 +2384,7 @@ class Query(
return _column_descriptions(self, legacy=True)
- def instances(self, result_proxy, context=None):
+ def instances(self, result_proxy: Result, context=None) -> Any:
"""Return an ORM result given a :class:`_engine.CursorResult` and
:class:`.QueryContext`.
@@ -2400,6 +2416,7 @@ class Query(
if result._attributes.get("filtered", False):
result = result.unique()
+ # TODO: isn't this supposed to be a list?
return result
@util.became_legacy_20(
@@ -2436,7 +2453,7 @@ class Query(
return loading.merge_result(self, iterator, load)
- def exists(self):
+ def exists(self) -> Exists:
"""A convenience method that turns a query into an EXISTS subquery
of the form EXISTS (SELECT 1 FROM ... WHERE ...).