Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
query.py3395 linesDownload Raw Back to orm
1# orm/query.py
2# Copyright (C) 2005-2024 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
7
8"""The Query class and support.
9
10Defines the :class:`_query.Query` class, the central
11construct used by the ORM to construct database queries.
12
13The :class:`_query.Query` class should not be confused with the
14:class:`_expression.Select` class, which defines database
15SELECT operations at the SQL (non-ORM) level.  ``Query`` differs from
16``Select`` in that it returns ORM-mapped objects and interacts with an
17ORM session, whereas the ``Select`` construct interacts directly with the
18database to return iterable result sets.
19
20"""
21from __future__ import annotations
22
23import collections.abc as collections_abc
24import operator
25from typing import Any
26from typing import Callable
27from typing import cast
28from typing import Dict
29from typing import Generic
30from typing import Iterable
31from typing import Iterator
32from typing import List
33from typing import Mapping
34from typing import Optional
35from typing import overload
36from typing import Sequence
37from typing import Tuple
38from typing import Type
39from typing import TYPE_CHECKING
40from typing import TypeVar
41from typing import Union
42
43from . import attributes
44from . import interfaces
45from . import loading
46from . import util as orm_util
47from ._typing import _O
48from .base import _assertions
49from .context import _column_descriptions
50from .context import _determine_last_joined_entity
51from .context import _legacy_filter_by_entity_zero
52from .context import FromStatement
53from .context import ORMCompileState
54from .context import QueryContext
55from .interfaces import ORMColumnDescription
56from .interfaces import ORMColumnsClauseRole
57from .util import AliasedClass
58from .util import object_mapper
59from .util import with_parent
60from .. import exc as sa_exc
61from .. import inspect
62from .. import inspection
63from .. import log
64from .. import sql
65from .. import util
66from ..engine import Result
67from ..engine import Row
68from ..event import dispatcher
69from ..event import EventTarget
70from ..sql import coercions
71from ..sql import expression
72from ..sql import roles
73from ..sql import Select
74from ..sql import util as sql_util
75from ..sql import visitors
76from ..sql._typing import _FromClauseArgument
77from ..sql._typing import _TP
78from ..sql.annotation import SupportsCloneAnnotations
79from ..sql.base import _entity_namespace_key
80from ..sql.base import _generative
81from ..sql.base import _NoArg
82from ..sql.base import Executable
83from ..sql.base import Generative
84from ..sql.elements import BooleanClauseList
85from ..sql.expression import Exists
86from ..sql.selectable import _MemoizedSelectEntities
87from ..sql.selectable import _SelectFromElements
88from ..sql.selectable import ForUpdateArg
89from ..sql.selectable import HasHints
90from ..sql.selectable import HasPrefixes
91from ..sql.selectable import HasSuffixes
92from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
93from ..sql.selectable import SelectLabelStyle
94from ..util.typing import Literal
95from ..util.typing import Self
96
97
98if TYPE_CHECKING:
99    from ._typing import _EntityType
100    from ._typing import _ExternalEntityType
101    from ._typing import _InternalEntityType
102    from ._typing import SynchronizeSessionArgument
103    from .mapper import Mapper
104    from .path_registry import PathRegistry
105    from .session import _PKIdentityArgument
106    from .session import Session
107    from .state import InstanceState
108    from ..engine.cursor import CursorResult
109    from ..engine.interfaces import _ImmutableExecuteOptions
110    from ..engine.interfaces import CompiledCacheType
111    from ..engine.interfaces import IsolationLevel
112    from ..engine.interfaces import SchemaTranslateMapType
113    from ..engine.result import FrozenResult
114    from ..engine.result import ScalarResult
115    from ..sql._typing import _ColumnExpressionArgument
116    from ..sql._typing import _ColumnExpressionOrStrLabelArgument
117    from ..sql._typing import _ColumnsClauseArgument
118    from ..sql._typing import _DMLColumnArgument
119    from ..sql._typing import _JoinTargetArgument
120    from ..sql._typing import _LimitOffsetType
121    from ..sql._typing import _MAYBE_ENTITY
122    from ..sql._typing import _no_kw
123    from ..sql._typing import _NOT_ENTITY
124    from ..sql._typing import _OnClauseArgument
125    from ..sql._typing import _PropagateAttrsType
126    from ..sql._typing import _T0
127    from ..sql._typing import _T1
128    from ..sql._typing import _T2
129    from ..sql._typing import _T3
130    from ..sql._typing import _T4
131    from ..sql._typing import _T5
132    from ..sql._typing import _T6
133    from ..sql._typing import _T7
134    from ..sql._typing import _TypedColumnClauseArgument as _TCCA
135    from ..sql.base import CacheableOptions
136    from ..sql.base import ExecutableOption
137    from ..sql.elements import ColumnElement
138    from ..sql.elements import Label
139    from ..sql.selectable import _ForUpdateOfArgument
140    from ..sql.selectable import _JoinTargetElement
141    from ..sql.selectable import _SetupJoinsElement
142    from ..sql.selectable import Alias
143    from ..sql.selectable import CTE
144    from ..sql.selectable import ExecutableReturnsRows
145    from ..sql.selectable import FromClause
146    from ..sql.selectable import ScalarSelect
147    from ..sql.selectable import Subquery
148
149
150__all__ = ["Query", "QueryContext"]
151
152_T = TypeVar("_T", bound=Any)
153
154
155@inspection._self_inspects
156@log.class_logger
157class Query(
158    _SelectFromElements,
159    SupportsCloneAnnotations,
160    HasPrefixes,
161    HasSuffixes,
162    HasHints,
163    EventTarget,
164    log.Identified,
165    Generative,
166    Executable,
167    Generic[_T],
168):
169    """ORM-level SQL construction object.
170
171    .. legacy:: The ORM :class:`.Query` object is a legacy construct
172       as of SQLAlchemy 2.0.   See the notes at the top of
173       :ref:`query_api_toplevel` for an overview, including links to migration
174       documentation.
175
176    :class:`_query.Query` objects are normally initially generated using the
177    :meth:`~.Session.query` method of :class:`.Session`, and in
178    less common cases by instantiating the :class:`_query.Query` directly and
179    associating with a :class:`.Session` using the
180    :meth:`_query.Query.with_session`
181    method.
182
183    """
184
185    # elements that are in Core and can be cached in the same way
186    _where_criteria: Tuple[ColumnElement[Any], ...] = ()
187    _having_criteria: Tuple[ColumnElement[Any], ...] = ()
188
189    _order_by_clauses: Tuple[ColumnElement[Any], ...] = ()
190    _group_by_clauses: Tuple[ColumnElement[Any], ...] = ()
191    _limit_clause: Optional[ColumnElement[Any]] = None
192    _offset_clause: Optional[ColumnElement[Any]] = None
193
194    _distinct: bool = False
195    _distinct_on: Tuple[ColumnElement[Any], ...] = ()
196
197    _for_update_arg: Optional[ForUpdateArg] = None
198    _correlate: Tuple[FromClause, ...] = ()
199    _auto_correlate: bool = True
200    _from_obj: Tuple[FromClause, ...] = ()
201    _setup_joins: Tuple[_SetupJoinsElement, ...] = ()
202
203    _label_style: SelectLabelStyle = SelectLabelStyle.LABEL_STYLE_LEGACY_ORM
204
205    _memoized_select_entities = ()
206
207    _compile_options: Union[Type[CacheableOptions], CacheableOptions] = (
208        ORMCompileState.default_compile_options
209    )
210
211    _with_options: Tuple[ExecutableOption, ...]
212    load_options = QueryContext.default_load_options + {
213        "_legacy_uniquing": True
214    }
215
216    _params: util.immutabledict[str, Any] = util.EMPTY_DICT
217
218    # local Query builder state, not needed for
219    # compilation or execution
220    _enable_assertions = True
221
222    _statement: Optional[ExecutableReturnsRows] = None
223
224    session: Session
225
226    dispatch: dispatcher[Query[_T]]
227
228    # mirrors that of ClauseElement, used to propagate the "orm"
229    # plugin as well as the "subject" of the plugin, e.g. the mapper
230    # we are querying against.
231    @util.memoized_property
232    def _propagate_attrs(self) -> _PropagateAttrsType:
233        return util.EMPTY_DICT
234
235    def __init__(
236        self,
237        entities: Union[
238            _ColumnsClauseArgument[Any], Sequence[_ColumnsClauseArgument[Any]]
239        ],
240        session: Optional[Session] = None,
241    ):
242        """Construct a :class:`_query.Query` directly.
243
244        E.g.::
245
246            q = Query([User, Address], session=some_session)
247
248        The above is equivalent to::
249
250            q = some_session.query(User, Address)
251
252        :param entities: a sequence of entities and/or SQL expressions.
253
254        :param session: a :class:`.Session` with which the
255         :class:`_query.Query`
256         will be associated.   Optional; a :class:`_query.Query`
257         can be associated
258         with a :class:`.Session` generatively via the
259         :meth:`_query.Query.with_session` method as well.
260
261        .. seealso::
262
263            :meth:`.Session.query`
264
265            :meth:`_query.Query.with_session`
266
267        """
268
269        # session is usually present.  There's one case in subqueryloader
270        # where it stores a Query without a Session and also there are tests
271        # for the query(Entity).with_session(session) API which is likely in
272        # some old recipes, however these are legacy as select() can now be
273        # used.
274        self.session = session  # type: ignore
275        self._set_entities(entities)
276
277    def _set_propagate_attrs(self, values: Mapping[str, Any]) -> Self:
278        self._propagate_attrs = util.immutabledict(values)
279        return self
280
281    def _set_entities(
282        self,
283        entities: Union[
284            _ColumnsClauseArgument[Any], Iterable[_ColumnsClauseArgument[Any]]
285        ],
286    ) -> None:
287        self._raw_columns = [
288            coercions.expect(
289                roles.ColumnsClauseRole,
290                ent,
291                apply_propagate_attrs=self,
292                post_inspect=True,
293            )
294            for ent in util.to_list(entities)
295        ]
296
297    def tuples(self: Query[_O]) -> Query[Tuple[_O]]:
298        """return a tuple-typed form of this :class:`.Query`.
299
300        This method invokes the :meth:`.Query.only_return_tuples`
301        method with a value of ``True``, which by itself ensures that this
302        :class:`.Query` will always return :class:`.Row` objects, even
303        if the query is made against a single entity.  It then also
304        at the typing level will return a "typed" query, if possible,
305        that will type result rows as ``Tuple`` objects with typed
306        elements.
307
308        This method can be compared to the :meth:`.Result.tuples` method,
309        which returns "self", but from a typing perspective returns an object
310        that will yield typed ``Tuple`` objects for results.   Typing
311        takes effect only if this :class:`.Query` object is a typed
312        query object already.
313
314        .. versionadded:: 2.0
315
316        .. seealso::
317
318            :meth:`.Result.tuples` - v2 equivalent method.
319
320        """
321        return self.only_return_tuples(True)  # type: ignore
322
323    def _entity_from_pre_ent_zero(self) -> Optional[_InternalEntityType[Any]]:
324        if not self._raw_columns:
325            return None
326
327        ent = self._raw_columns[0]
328
329        if "parententity" in ent._annotations:
330            return ent._annotations["parententity"]  # type: ignore
331        elif "bundle" in ent._annotations:
332            return ent._annotations["bundle"]  # type: ignore
333        else:
334            # label, other SQL expression
335            for element in visitors.iterate(ent):
336                if "parententity" in element._annotations:
337                    return element._annotations["parententity"]  # type: ignore  # noqa: E501
338            else:
339                return None
340
341    def _only_full_mapper_zero(self, methname: str) -> Mapper[Any]:
342        if (
343            len(self._raw_columns) != 1
344            or "parententity" not in self._raw_columns[0]._annotations
345            or not self._raw_columns[0].is_selectable
346        ):
347            raise sa_exc.InvalidRequestError(
348                "%s() can only be used against "
349                "a single mapped class." % methname
350            )
351
352        return self._raw_columns[0]._annotations["parententity"]  # type: ignore  # noqa: E501
353
354    def _set_select_from(
355        self, obj: Iterable[_FromClauseArgument], set_base_alias: bool
356    ) -> None:
357        fa = [
358            coercions.expect(
359                roles.StrictFromClauseRole,
360                elem,
361                allow_select=True,
362                apply_propagate_attrs=self,
363            )
364            for elem in obj
365        ]
366
367        self._compile_options += {"_set_base_alias": set_base_alias}
368        self._from_obj = tuple(fa)
369
370    @_generative
371    def _set_lazyload_from(self, state: InstanceState[Any]) -> Self:
372        self.load_options += {"_lazy_loaded_from": state}
373        return self
374
375    def _get_condition(self) -> None:
376        """used by legacy BakedQuery"""
377        self._no_criterion_condition("get", order_by=False, distinct=False)
378
379    def _get_existing_condition(self) -> None:
380        self._no_criterion_assertion("get", order_by=False, distinct=False)
381
382    def _no_criterion_assertion(
383        self, meth: str, order_by: bool = True, distinct: bool = True
384    ) -> None:
385        if not self._enable_assertions:
386            return
387        if (
388            self._where_criteria
389            or self._statement is not None
390            or self._from_obj
391            or self._setup_joins
392            or self._limit_clause is not None
393            or self._offset_clause is not None
394            or self._group_by_clauses
395            or (order_by and self._order_by_clauses)
396            or (distinct and self._distinct)
397        ):
398            raise sa_exc.InvalidRequestError(
399                "Query.%s() being called on a "
400                "Query with existing criterion. " % meth
401            )
402
403    def _no_criterion_condition(
404        self, meth: str, order_by: bool = True, distinct: bool = True
405    ) -> None:
406        self._no_criterion_assertion(meth, order_by, distinct)
407
408        self._from_obj = self._setup_joins = ()
409        if self._statement is not None:
410            self._compile_options += {"_statement": None}
411        self._where_criteria = ()
412        self._distinct = False
413
414        self._order_by_clauses = self._group_by_clauses = ()
415
416    def _no_clauseelement_condition(self, meth: str) -> None:
417        if not self._enable_assertions:
418            return
419        if self._order_by_clauses:
420            raise sa_exc.InvalidRequestError(
421                "Query.%s() being called on a "
422                "Query with existing criterion. " % meth
423            )
424        self._no_criterion_condition(meth)
425
426    def _no_statement_condition(self, meth: str) -> None:
427        if not self._enable_assertions:
428            return
429        if self._statement is not None:
430            raise sa_exc.InvalidRequestError(
431                (
432                    "Query.%s() being called on a Query with an existing full "
433                    "statement - can't apply criterion."
434                )
435                % meth
436            )
437
438    def _no_limit_offset(self, meth: str) -> None:
439        if not self._enable_assertions:
440            return
441        if self._limit_clause is not None or self._offset_clause is not None:
442            raise sa_exc.InvalidRequestError(
443                "Query.%s() being called on a Query which already has LIMIT "
444                "or OFFSET applied.  Call %s() before limit() or offset() "
445                "are applied." % (meth, meth)
446            )
447
448    @property
449    def _has_row_limiting_clause(self) -> bool:
450        return (
451            self._limit_clause is not None or self._offset_clause is not None
452        )
453
454    def _get_options(
455        self,
456        populate_existing: Optional[bool] = None,
457        version_check: Optional[bool] = None,
458        only_load_props: Optional[Sequence[str]] = None,
459        refresh_state: Optional[InstanceState[Any]] = None,
460        identity_token: Optional[Any] = None,
461    ) -> Self:
462        load_options: Dict[str, Any] = {}
463        compile_options: Dict[str, Any] = {}
464
465        if version_check:
466            load_options["_version_check"] = version_check
467        if populate_existing:
468            load_options["_populate_existing"] = populate_existing
469        if refresh_state:
470            load_options["_refresh_state"] = refresh_state
471            compile_options["_for_refresh_state"] = True
472        if only_load_props:
473            compile_options["_only_load_props"] = frozenset(only_load_props)
474        if identity_token:
475            load_options["_identity_token"] = identity_token
476
477        if load_options:
478            self.load_options += load_options
479        if compile_options:
480            self._compile_options += compile_options
481
482        return self
483
484    def _clone(self, **kw: Any) -> Self:
485        return self._generate()
486
487    def _get_select_statement_only(self) -> Select[_T]:
488        if self._statement is not None:
489            raise sa_exc.InvalidRequestError(
490                "Can't call this method on a Query that uses from_statement()"
491            )
492        return cast("Select[_T]", self.statement)
493
494    @property
495    def statement(self) -> Union[Select[_T], FromStatement[_T]]:
496        """The full SELECT statement represented by this Query.
497
498        The statement by default will not have disambiguating labels
499        applied to the construct unless with_labels(True) is called
500        first.
501
502        """
503
504        # .statement can return the direct future.Select() construct here, as
505        # long as we are not using subsequent adaption features that
506        # are made against raw entities, e.g. from_self(), with_polymorphic(),
507        # select_entity_from().  If these features are being used, then
508        # the Select() we return will not have the correct .selected_columns
509        # collection and will not embed in subsequent queries correctly.
510        # We could find a way to make this collection "correct", however
511        # this would not be too different from doing the full compile as
512        # we are doing in any case, the Select() would still not have the
513        # proper state for other attributes like whereclause, order_by,
514        # and these features are all deprecated in any case.
515        #
516        # for these reasons, Query is not a Select, it remains an ORM
517        # object for which __clause_element__() must be called in order for
518        # it to provide a real expression object.
519        #
520        # from there, it starts to look much like Query itself won't be
521        # passed into the execute process and won't generate its own cache
522        # key; this will all occur in terms of the ORM-enabled Select.
523        if not self._compile_options._set_base_alias:
524            # if we don't have legacy top level aliasing features in use
525            # then convert to a future select() directly
526            stmt = self._statement_20(for_statement=True)
527        else:
528            stmt = self._compile_state(for_statement=True).statement
529
530        if self._params:
531            stmt = stmt.params(self._params)
532
533        return stmt
534
535    def _final_statement(self, legacy_query_style: bool = True) -> Select[Any]:
536        """Return the 'final' SELECT statement for this :class:`.Query`.
537
538        This is used by the testing suite only and is fairly inefficient.
539
540        This is the Core-only select() that will be rendered by a complete
541        compilation of this query, and is what .statement used to return
542        in 1.3.
543
544
545        """
546
547        q = self._clone()
548
549        return q._compile_state(
550            use_legacy_query_style=legacy_query_style
551        ).statement  # type: ignore
552
553    def _statement_20(
554        self, for_statement: bool = False, use_legacy_query_style: bool = True
555    ) -> Union[Select[_T], FromStatement[_T]]:
556        # TODO: this event needs to be deprecated, as it currently applies
557        # only to ORM query and occurs at this spot that is now more
558        # or less an artificial spot
559        if self.dispatch.before_compile:
560            for fn in self.dispatch.before_compile:
561                new_query = fn(self)
562                if new_query is not None and new_query is not self:
563                    self = new_query
564                    if not fn._bake_ok:  # type: ignore
565                        self._compile_options += {"_bake_ok": False}
566
567        compile_options = self._compile_options
568        compile_options += {
569            "_for_statement": for_statement,
570            "_use_legacy_query_style": use_legacy_query_style,
571        }
572
573        stmt: Union[Select[_T], FromStatement[_T]]
574
575        if self._statement is not None:
576            stmt = FromStatement(self._raw_columns, self._statement)
577            stmt.__dict__.update(
578                _with_options=self._with_options,
579                _with_context_options=self._with_context_options,
580                _compile_options=compile_options,
581                _execution_options=self._execution_options,
582                _propagate_attrs=self._propagate_attrs,
583            )
584        else:
585            # Query / select() internal attributes are 99% cross-compatible
586            stmt = Select._create_raw_select(**self.__dict__)
587            stmt.__dict__.update(
588                _label_style=self._label_style,
589                _compile_options=compile_options,
590                _propagate_attrs=self._propagate_attrs,
591            )
592            stmt.__dict__.pop("session", None)
593
594        # ensure the ORM context is used to compile the statement, even
595        # if it has no ORM entities.  This is so ORM-only things like
596        # _legacy_joins are picked up that wouldn't be picked up by the
597        # Core statement context
598        if "compile_state_plugin" not in stmt._propagate_attrs:
599            stmt._propagate_attrs = stmt._propagate_attrs.union(
600                {"compile_state_plugin": "orm", "plugin_subject": None}
601            )
602
603        return stmt
604
605    def subquery(
606        self,
607        name: Optional[str] = None,
608        with_labels: bool = False,
609        reduce_columns: bool = False,
610    ) -> Subquery:
611        """Return the full SELECT statement represented by
612        this :class:`_query.Query`, embedded within an
613        :class:`_expression.Alias`.
614
615        Eager JOIN generation within the query is disabled.
616
617        .. seealso::
618
619            :meth:`_sql.Select.subquery` - v2 comparable method.
620
621        :param name: string name to be assigned as the alias;
622            this is passed through to :meth:`_expression.FromClause.alias`.
623            If ``None``, a name will be deterministically generated
624            at compile time.
625
626        :param with_labels: if True, :meth:`.with_labels` will be called
627         on the :class:`_query.Query` first to apply table-qualified labels
628         to all columns.
629
630        :param reduce_columns: if True,
631         :meth:`_expression.Select.reduce_columns` will
632         be called on the resulting :func:`_expression.select` construct,
633         to remove same-named columns where one also refers to the other
634         via foreign key or WHERE clause equivalence.
635
636        """
637        q = self.enable_eagerloads(False)
638        if with_labels:
639            q = q.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
640
641        stmt = q._get_select_statement_only()
642
643        if TYPE_CHECKING:
644            assert isinstance(stmt, Select)
645
646        if reduce_columns:
647            stmt = stmt.reduce_columns()
648        return stmt.subquery(name=name)
649
650    def cte(
651        self,
652        name: Optional[str] = None,
653        recursive: bool = False,
654        nesting: bool = False,
655    ) -> CTE:
656        r"""Return the full SELECT statement represented by this
657        :class:`_query.Query` represented as a common table expression (CTE).
658
659        Parameters and usage are the same as those of the
660        :meth:`_expression.SelectBase.cte` method; see that method for
661        further details.
662
663        Here is the `PostgreSQL WITH
664        RECURSIVE example
665        <https://www.postgresql.org/docs/current/static/queries-with.html>`_.
666        Note that, in this example, the ``included_parts`` cte and the
667        ``incl_alias`` alias of it are Core selectables, which
668        means the columns are accessed via the ``.c.`` attribute.  The
669        ``parts_alias`` object is an :func:`_orm.aliased` instance of the
670        ``Part`` entity, so column-mapped attributes are available
671        directly::
672
673            from sqlalchemy.orm import aliased
674
675            class Part(Base):
676                __tablename__ = 'part'
677                part = Column(String, primary_key=True)
678                sub_part = Column(String, primary_key=True)
679                quantity = Column(Integer)
680
681            included_parts = session.query(
682                            Part.sub_part,
683                            Part.part,
684                            Part.quantity).\
685                                filter(Part.part=="our part").\
686                                cte(name="included_parts", recursive=True)
687
688            incl_alias = aliased(included_parts, name="pr")
689            parts_alias = aliased(Part, name="p")
690            included_parts = included_parts.union_all(
691                session.query(
692                    parts_alias.sub_part,
693                    parts_alias.part,
694                    parts_alias.quantity).\
695                        filter(parts_alias.part==incl_alias.c.sub_part)
696                )
697
698            q = session.query(
699                    included_parts.c.sub_part,
700                    func.sum(included_parts.c.quantity).
701                        label('total_quantity')
702                ).\
703                group_by(included_parts.c.sub_part)
704
705        .. seealso::
706
707            :meth:`_sql.Select.cte` - v2 equivalent method.
708
709        """
710        return (
711            self.enable_eagerloads(False)
712            ._get_select_statement_only()
713            .cte(name=name, recursive=recursive, nesting=nesting)
714        )
715
716    def label(self, name: Optional[str]) -> Label[Any]:
717        """Return the full SELECT statement represented by this
718        :class:`_query.Query`, converted
719        to a scalar subquery with a label of the given name.
720
721        .. seealso::
722
723            :meth:`_sql.Select.label` - v2 comparable method.
724
725        """
726
727        return (
728            self.enable_eagerloads(False)
729            ._get_select_statement_only()
730            .label(name)
731        )
732
733    @overload
734    def as_scalar(
735        self: Query[Tuple[_MAYBE_ENTITY]],
736    ) -> ScalarSelect[_MAYBE_ENTITY]: ...
737
738    @overload
739    def as_scalar(
740        self: Query[Tuple[_NOT_ENTITY]],
741    ) -> ScalarSelect[_NOT_ENTITY]: ...
742
743    @overload
744    def as_scalar(self) -> ScalarSelect[Any]: ...
745
746    @util.deprecated(
747        "1.4",
748        "The :meth:`_query.Query.as_scalar` method is deprecated and will be "
749        "removed in a future release.  Please refer to "
750        ":meth:`_query.Query.scalar_subquery`.",
751    )
752    def as_scalar(self) -> ScalarSelect[Any]:
753        """Return the full SELECT statement represented by this
754        :class:`_query.Query`, converted to a scalar subquery.
755
756        """
757        return self.scalar_subquery()
758
759    @overload
760    def scalar_subquery(
761        self: Query[Tuple[_MAYBE_ENTITY]],
762    ) -> ScalarSelect[Any]: ...
763
764    @overload
765    def scalar_subquery(
766        self: Query[Tuple[_NOT_ENTITY]],
767    ) -> ScalarSelect[_NOT_ENTITY]: ...
768
769    @overload
770    def scalar_subquery(self) -> ScalarSelect[Any]: ...
771
772    def scalar_subquery(self) -> ScalarSelect[Any]:
773        """Return the full SELECT statement represented by this
774        :class:`_query.Query`, converted to a scalar subquery.
775
776        Analogous to
777        :meth:`sqlalchemy.sql.expression.SelectBase.scalar_subquery`.
778
779        .. versionchanged:: 1.4 The :meth:`_query.Query.scalar_subquery`
780           method replaces the :meth:`_query.Query.as_scalar` method.
781
782        .. seealso::
783
784            :meth:`_sql.Select.scalar_subquery` - v2 comparable method.
785
786        """
787
788        return (
789            self.enable_eagerloads(False)
790            ._get_select_statement_only()
791            .scalar_subquery()
792        )
793
794    @property
795    def selectable(self) -> Union[Select[_T], FromStatement[_T]]:
796        """Return the :class:`_expression.Select` object emitted by this
797        :class:`_query.Query`.
798
799        Used for :func:`_sa.inspect` compatibility, this is equivalent to::
800
801            query.enable_eagerloads(False).with_labels().statement
802
803        """
804        return self.__clause_element__()
805
806    def __clause_element__(self) -> Union[Select[_T], FromStatement[_T]]:
807        return (
808            self._with_compile_options(
809                _enable_eagerloads=False, _render_for_subquery=True
810            )
811            .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
812            .statement
813        )
814
815    @overload
816    def only_return_tuples(
817        self: Query[_O], value: Literal[True]
818    ) -> RowReturningQuery[Tuple[_O]]: ...
819
820    @overload
821    def only_return_tuples(
822        self: Query[_O], value: Literal[False]
823    ) -> Query[_O]: ...
824
825    @_generative
826    def only_return_tuples(self, value: bool) -> Query[Any]:
827        """When set to True, the query results will always be a
828        :class:`.Row` object.
829
830        This can change a query that normally returns a single entity
831        as a scalar to return a :class:`.Row` result in all cases.
832
833        .. seealso::
834
835            :meth:`.Query.tuples` - returns tuples, but also at the typing
836            level will type results as ``Tuple``.
837
838            :meth:`_query.Query.is_single_entity`
839
840            :meth:`_engine.Result.tuples` - v2 comparable method.
841
842        """
843        self.load_options += dict(_only_return_tuples=value)
844        return self
845
846    @property
847    def is_single_entity(self) -> bool:
848        """Indicates if this :class:`_query.Query`
849        returns tuples or single entities.
850
851        Returns True if this query returns a single entity for each instance
852        in its result list, and False if this query returns a tuple of entities
853        for each result.
854
855        .. versionadded:: 1.3.11
856
857        .. seealso::
858
859            :meth:`_query.Query.only_return_tuples`
860
861        """
862        return (
863            not self.load_options._only_return_tuples
864            and len(self._raw_columns) == 1
865            and "parententity" in self._raw_columns[0]._annotations
866            and isinstance(
867                self._raw_columns[0]._annotations["parententity"],
868                ORMColumnsClauseRole,
869            )
870        )
871
872    @_generative
873    def enable_eagerloads(self, value: bool) -> Self:
874        """Control whether or not eager joins and subqueries are
875        rendered.
876
877        When set to False, the returned Query will not render
878        eager joins regardless of :func:`~sqlalchemy.orm.joinedload`,
879        :func:`~sqlalchemy.orm.subqueryload` options
880        or mapper-level ``lazy='joined'``/``lazy='subquery'``
881        configurations.
882
883        This is used primarily when nesting the Query's
884        statement into a subquery or other
885        selectable, or when using :meth:`_query.Query.yield_per`.
886
887        """
888        self._compile_options += {"_enable_eagerloads": value}
889        return self
890
891    @_generative
892    def _with_compile_options(self, **opt: Any) -> Self:
893        self._compile_options += opt
894        return self
895
896    @util.became_legacy_20(
897        ":meth:`_orm.Query.with_labels` and :meth:`_orm.Query.apply_labels`",
898        alternative="Use set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) "
899        "instead.",
900    )
901    def with_labels(self) -> Self:
902        return self.set_label_style(
903            SelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COL
904        )
905
906    apply_labels = with_labels
907
908    @property
909    def get_label_style(self) -> SelectLabelStyle:
910        """
911        Retrieve the current label style.
912
913        .. versionadded:: 1.4
914
915        .. seealso::
916
917            :meth:`_sql.Select.get_label_style` - v2 equivalent method.
918
919        """
920        return self._label_style
921
922    def set_label_style(self, style: SelectLabelStyle) -> Self:
923        """Apply column labels to the return value of Query.statement.
924
925        Indicates that this Query's `statement` accessor should return
926        a SELECT statement that applies labels to all columns in the
927        form <tablename>_<columnname>; this is commonly used to
928        disambiguate columns from multiple tables which have the same
929        name.
930
931        When the `Query` actually issues SQL to load rows, it always
932        uses column labeling.
933
934        .. note:: The :meth:`_query.Query.set_label_style` method *only* applies
935           the output of :attr:`_query.Query.statement`, and *not* to any of
936           the result-row invoking systems of :class:`_query.Query` itself,
937           e.g.
938           :meth:`_query.Query.first`, :meth:`_query.Query.all`, etc.
939           To execute
940           a query using :meth:`_query.Query.set_label_style`, invoke the
941           :attr:`_query.Query.statement` using :meth:`.Session.execute`::
942
943                result = session.execute(
944                    query
945                    .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
946                    .statement
947                )
948
949        .. versionadded:: 1.4
950
951
952        .. seealso::
953
954            :meth:`_sql.Select.set_label_style` - v2 equivalent method.
955
956        """  # noqa
957        if self._label_style is not style:
958            self = self._generate()
959            self._label_style = style
960        return self
961
962    @_generative
963    def enable_assertions(self, value: bool) -> Self:
964        """Control whether assertions are generated.
965
966        When set to False, the returned Query will
967        not assert its state before certain operations,
968        including that LIMIT/OFFSET has not been applied
969        when filter() is called, no criterion exists
970        when get() is called, and no "from_statement()"
971        exists when filter()/order_by()/group_by() etc.
972        is called.  This more permissive mode is used by
973        custom Query subclasses to specify criterion or
974        other modifiers outside of the usual usage patterns.
975
976        Care should be taken to ensure that the usage
977        pattern is even possible.  A statement applied
978        by from_statement() will override any criterion
979        set by filter() or order_by(), for example.
980
981        """
982        self._enable_assertions = value
983        return self
984
985    @property
986    def whereclause(self) -> Optional[ColumnElement[bool]]:
987        """A readonly attribute which returns the current WHERE criterion for
988        this Query.
989
990        This returned value is a SQL expression construct, or ``None`` if no
991        criterion has been established.
992
993        .. seealso::
994
995            :attr:`_sql.Select.whereclause` - v2 equivalent property.
996
997        """
998        return BooleanClauseList._construct_for_whereclause(
999            self._where_criteria
1000        )
1001
1002    @_generative
1003    def _with_current_path(self, path: PathRegistry) -> Self:
1004        """indicate that this query applies to objects loaded
1005        within a certain path.
1006
1007        Used by deferred loaders (see strategies.py) which transfer
1008        query options from an originating query to a newly generated
1009        query intended for the deferred load.
1010
1011        """
1012        self._compile_options += {"_current_path": path}
1013        return self
1014
1015    @_generative
1016    def yield_per(self, count: int) -> Self:
1017        r"""Yield only ``count`` rows at a time.
1018
1019        The purpose of this method is when fetching very large result sets
1020        (> 10K rows), to batch results in sub-collections and yield them
1021        out partially, so that the Python interpreter doesn't need to declare
1022        very large areas of memory which is both time consuming and leads
1023        to excessive memory use.   The performance from fetching hundreds of
1024        thousands of rows can often double when a suitable yield-per setting
1025        (e.g. approximately 1000) is used, even with DBAPIs that buffer
1026        rows (which are most).
1027
1028        As of SQLAlchemy 1.4, the :meth:`_orm.Query.yield_per` method is
1029        equivalent to using the ``yield_per`` execution option at the ORM
1030        level. See the section :ref:`orm_queryguide_yield_per` for further
1031        background on this option.
1032
1033        .. seealso::
1034
1035            :ref:`orm_queryguide_yield_per`
1036
1037        """
1038        self.load_options += {"_yield_per": count}
1039        return self
1040
1041    @util.became_legacy_20(
1042        ":meth:`_orm.Query.get`",
1043        alternative="The method is now available as :meth:`_orm.Session.get`",
1044    )
1045    def get(self, ident: _PKIdentityArgument) -> Optional[Any]:
1046        """Return an instance based on the given primary key identifier,
1047        or ``None`` if not found.
1048
1049        E.g.::
1050
1051            my_user = session.query(User).get(5)
1052
1053            some_object = session.query(VersionedFoo).get((5, 10))
1054
1055            some_object = session.query(VersionedFoo).get(
1056                {"id": 5, "version_id": 10})
1057
1058        :meth:`_query.Query.get` is special in that it provides direct
1059        access to the identity map of the owning :class:`.Session`.
1060        If the given primary key identifier is present
1061        in the local identity map, the object is returned
1062        directly from this collection and no SQL is emitted,
1063        unless the object has been marked fully expired.
1064        If not present,
1065        a SELECT is performed in order to locate the object.
1066
1067        :meth:`_query.Query.get` also will perform a check if
1068        the object is present in the identity map and
1069        marked as expired - a SELECT
1070        is emitted to refresh the object as well as to
1071        ensure that the row is still present.
1072        If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.
1073
1074        :meth:`_query.Query.get` is only used to return a single
1075        mapped instance, not multiple instances or
1076        individual column constructs, and strictly
1077        on a single primary key value.  The originating
1078        :class:`_query.Query` must be constructed in this way,
1079        i.e. against a single mapped entity,
1080        with no additional filtering criterion.  Loading
1081        options via :meth:`_query.Query.options` may be applied
1082        however, and will be used if the object is not
1083        yet locally present.
1084
1085        :param ident: A scalar, tuple, or dictionary representing the
1086         primary key.  For a composite (e.g. multiple column) primary key,
1087         a tuple or dictionary should be passed.
1088
1089         For a single-column primary key, the scalar calling form is typically
1090         the most expedient.  If the primary key of a row is the value "5",
1091         the call looks like::
1092
1093            my_object = query.get(5)
1094
1095         The tuple form contains primary key values typically in
1096         the order in which they correspond to the mapped
1097         :class:`_schema.Table`
1098         object's primary key columns, or if the
1099         :paramref:`_orm.Mapper.primary_key` configuration parameter were
1100         used, in
1101         the order used for that parameter. For example, if the primary key
1102         of a row is represented by the integer
1103         digits "5, 10" the call would look like::
1104
1105             my_object = query.get((5, 10))
1106
1107         The dictionary form should include as keys the mapped attribute names
1108         corresponding to each element of the primary key.  If the mapped class
1109         has the attributes ``id``, ``version_id`` as the attributes which
1110         store the object's primary key value, the call would look like::
1111
1112            my_object = query.get({"id": 5, "version_id": 10})
1113
1114         .. versionadded:: 1.3 the :meth:`_query.Query.get`
1115            method now optionally
1116            accepts a dictionary of attribute names to values in order to
1117            indicate a primary key identifier.
1118
1119
1120        :return: The object instance, or ``None``.
1121
1122        """
1123        self._no_criterion_assertion("get", order_by=False, distinct=False)
1124
1125        # we still implement _get_impl() so that baked query can override
1126        # it
1127        return self._get_impl(ident, loading.load_on_pk_identity)
1128
1129    def _get_impl(
1130        self,
1131        primary_key_identity: _PKIdentityArgument,
1132        db_load_fn: Callable[..., Any],
1133        identity_token: Optional[Any] = None,
1134    ) -> Optional[Any]:
1135        mapper = self._only_full_mapper_zero("get")
1136        return self.session._get_impl(
1137            mapper,
1138            primary_key_identity,
1139            db_load_fn,
1140            populate_existing=self.load_options._populate_existing,
1141            with_for_update=self._for_update_arg,
1142            options=self._with_options,
1143            identity_token=identity_token,
1144            execution_options=self._execution_options,
1145        )
1146
1147    @property
1148    def lazy_loaded_from(self) -> Optional[InstanceState[Any]]:
1149        """An :class:`.InstanceState` that is using this :class:`_query.Query`
1150        for a lazy load operation.
1151
1152        .. deprecated:: 1.4  This attribute should be viewed via the
1153           :attr:`.ORMExecuteState.lazy_loaded_from` attribute, within
1154           the context of the :meth:`.SessionEvents.do_orm_execute`
1155           event.
1156
1157        .. seealso::
1158
1159            :attr:`.ORMExecuteState.lazy_loaded_from`
1160
1161        """
1162        return self.load_options._lazy_loaded_from  # type: ignore
1163
1164    @property
1165    def _current_path(self) -> PathRegistry:
1166        return self._compile_options._current_path  # type: ignore
1167
1168    @_generative
1169    def correlate(
1170        self,
1171        *fromclauses: Union[Literal[None, False], _FromClauseArgument],
1172    ) -> Self:
1173        """Return a :class:`.Query` construct which will correlate the given
1174        FROM clauses to that of an enclosing :class:`.Query` or
1175        :func:`~.expression.select`.
1176
1177        The method here accepts mapped classes, :func:`.aliased` constructs,
1178        and :class:`_orm.Mapper` constructs as arguments, which are resolved
1179        into expression constructs, in addition to appropriate expression
1180        constructs.
1181
1182        The correlation arguments are ultimately passed to
1183        :meth:`_expression.Select.correlate`
1184        after coercion to expression constructs.
1185
1186        The correlation arguments take effect in such cases
1187        as when :meth:`_query.Query.from_self` is used, or when
1188        a subquery as returned by :meth:`_query.Query.subquery` is
1189        embedded in another :func:`_expression.select` construct.
1190
1191        .. seealso::
1192
1193            :meth:`_sql.Select.correlate` - v2 equivalent method.
1194
1195        """
1196
1197        self._auto_correlate = False
1198        if fromclauses and fromclauses[0] in {None, False}:
1199            self._correlate = ()
1200        else:

Showing the first 1,200 of 3395 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai