query.py 116 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453
  1. # orm/query.py
  2. # Copyright (C) 2005-2025 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. """The Query class and support.
  8. Defines the :class:`_query.Query` class, the central
  9. construct used by the ORM to construct database queries.
  10. The :class:`_query.Query` class should not be confused with the
  11. :class:`_expression.Select` class, which defines database
  12. SELECT operations at the SQL (non-ORM) level. ``Query`` differs from
  13. ``Select`` in that it returns ORM-mapped objects and interacts with an
  14. ORM session, whereas the ``Select`` construct interacts directly with the
  15. database to return iterable result sets.
  16. """
  17. from __future__ import annotations
  18. import collections.abc as collections_abc
  19. import operator
  20. from typing import Any
  21. from typing import Callable
  22. from typing import cast
  23. from typing import Dict
  24. from typing import Generic
  25. from typing import Iterable
  26. from typing import Iterator
  27. from typing import List
  28. from typing import Mapping
  29. from typing import Optional
  30. from typing import overload
  31. from typing import Sequence
  32. from typing import Tuple
  33. from typing import Type
  34. from typing import TYPE_CHECKING
  35. from typing import TypeVar
  36. from typing import Union
  37. from . import attributes
  38. from . import interfaces
  39. from . import loading
  40. from . import util as orm_util
  41. from ._typing import _O
  42. from .base import _assertions
  43. from .context import _column_descriptions
  44. from .context import _determine_last_joined_entity
  45. from .context import _legacy_filter_by_entity_zero
  46. from .context import FromStatement
  47. from .context import ORMCompileState
  48. from .context import QueryContext
  49. from .interfaces import ORMColumnDescription
  50. from .interfaces import ORMColumnsClauseRole
  51. from .util import AliasedClass
  52. from .util import object_mapper
  53. from .util import with_parent
  54. from .. import exc as sa_exc
  55. from .. import inspect
  56. from .. import inspection
  57. from .. import log
  58. from .. import sql
  59. from .. import util
  60. from ..engine import Result
  61. from ..engine import Row
  62. from ..event import dispatcher
  63. from ..event import EventTarget
  64. from ..sql import coercions
  65. from ..sql import expression
  66. from ..sql import roles
  67. from ..sql import Select
  68. from ..sql import util as sql_util
  69. from ..sql import visitors
  70. from ..sql._typing import _FromClauseArgument
  71. from ..sql._typing import _TP
  72. from ..sql.annotation import SupportsCloneAnnotations
  73. from ..sql.base import _entity_namespace_key
  74. from ..sql.base import _generative
  75. from ..sql.base import _NoArg
  76. from ..sql.base import Executable
  77. from ..sql.base import Generative
  78. from ..sql.elements import BooleanClauseList
  79. from ..sql.expression import Exists
  80. from ..sql.selectable import _MemoizedSelectEntities
  81. from ..sql.selectable import _SelectFromElements
  82. from ..sql.selectable import ForUpdateArg
  83. from ..sql.selectable import HasHints
  84. from ..sql.selectable import HasPrefixes
  85. from ..sql.selectable import HasSuffixes
  86. from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL
  87. from ..sql.selectable import SelectLabelStyle
  88. from ..util.typing import Literal
  89. from ..util.typing import Self
  90. if TYPE_CHECKING:
  91. from ._typing import _EntityType
  92. from ._typing import _ExternalEntityType
  93. from ._typing import _InternalEntityType
  94. from ._typing import SynchronizeSessionArgument
  95. from .mapper import Mapper
  96. from .path_registry import PathRegistry
  97. from .session import _PKIdentityArgument
  98. from .session import Session
  99. from .state import InstanceState
  100. from ..engine.cursor import CursorResult
  101. from ..engine.interfaces import _ImmutableExecuteOptions
  102. from ..engine.interfaces import CompiledCacheType
  103. from ..engine.interfaces import IsolationLevel
  104. from ..engine.interfaces import SchemaTranslateMapType
  105. from ..engine.result import FrozenResult
  106. from ..engine.result import ScalarResult
  107. from ..sql._typing import _ColumnExpressionArgument
  108. from ..sql._typing import _ColumnExpressionOrStrLabelArgument
  109. from ..sql._typing import _ColumnsClauseArgument
  110. from ..sql._typing import _DMLColumnArgument
  111. from ..sql._typing import _JoinTargetArgument
  112. from ..sql._typing import _LimitOffsetType
  113. from ..sql._typing import _MAYBE_ENTITY
  114. from ..sql._typing import _no_kw
  115. from ..sql._typing import _NOT_ENTITY
  116. from ..sql._typing import _OnClauseArgument
  117. from ..sql._typing import _PropagateAttrsType
  118. from ..sql._typing import _T0
  119. from ..sql._typing import _T1
  120. from ..sql._typing import _T2
  121. from ..sql._typing import _T3
  122. from ..sql._typing import _T4
  123. from ..sql._typing import _T5
  124. from ..sql._typing import _T6
  125. from ..sql._typing import _T7
  126. from ..sql._typing import _TypedColumnClauseArgument as _TCCA
  127. from ..sql.base import CacheableOptions
  128. from ..sql.base import ExecutableOption
  129. from ..sql.dml import UpdateBase
  130. from ..sql.elements import ColumnElement
  131. from ..sql.elements import Label
  132. from ..sql.selectable import _ForUpdateOfArgument
  133. from ..sql.selectable import _JoinTargetElement
  134. from ..sql.selectable import _SetupJoinsElement
  135. from ..sql.selectable import Alias
  136. from ..sql.selectable import CTE
  137. from ..sql.selectable import ExecutableReturnsRows
  138. from ..sql.selectable import FromClause
  139. from ..sql.selectable import ScalarSelect
  140. from ..sql.selectable import Subquery
  141. __all__ = ["Query", "QueryContext"]
  142. _T = TypeVar("_T", bound=Any)
  143. @inspection._self_inspects
  144. @log.class_logger
  145. class Query(
  146. _SelectFromElements,
  147. SupportsCloneAnnotations,
  148. HasPrefixes,
  149. HasSuffixes,
  150. HasHints,
  151. EventTarget,
  152. log.Identified,
  153. Generative,
  154. Executable,
  155. Generic[_T],
  156. ):
  157. """ORM-level SQL construction object.
  158. .. legacy:: The ORM :class:`.Query` object is a legacy construct
  159. as of SQLAlchemy 2.0. See the notes at the top of
  160. :ref:`query_api_toplevel` for an overview, including links to migration
  161. documentation.
  162. :class:`_query.Query` objects are normally initially generated using the
  163. :meth:`~.Session.query` method of :class:`.Session`, and in
  164. less common cases by instantiating the :class:`_query.Query` directly and
  165. associating with a :class:`.Session` using the
  166. :meth:`_query.Query.with_session`
  167. method.
  168. """
  169. # elements that are in Core and can be cached in the same way
  170. _where_criteria: Tuple[ColumnElement[Any], ...] = ()
  171. _having_criteria: Tuple[ColumnElement[Any], ...] = ()
  172. _order_by_clauses: Tuple[ColumnElement[Any], ...] = ()
  173. _group_by_clauses: Tuple[ColumnElement[Any], ...] = ()
  174. _limit_clause: Optional[ColumnElement[Any]] = None
  175. _offset_clause: Optional[ColumnElement[Any]] = None
  176. _distinct: bool = False
  177. _distinct_on: Tuple[ColumnElement[Any], ...] = ()
  178. _for_update_arg: Optional[ForUpdateArg] = None
  179. _correlate: Tuple[FromClause, ...] = ()
  180. _auto_correlate: bool = True
  181. _from_obj: Tuple[FromClause, ...] = ()
  182. _setup_joins: Tuple[_SetupJoinsElement, ...] = ()
  183. _label_style: SelectLabelStyle = SelectLabelStyle.LABEL_STYLE_LEGACY_ORM
  184. _memoized_select_entities = ()
  185. _compile_options: Union[Type[CacheableOptions], CacheableOptions] = (
  186. ORMCompileState.default_compile_options
  187. )
  188. _with_options: Tuple[ExecutableOption, ...]
  189. load_options = QueryContext.default_load_options + {
  190. "_legacy_uniquing": True
  191. }
  192. _params: util.immutabledict[str, Any] = util.EMPTY_DICT
  193. # local Query builder state, not needed for
  194. # compilation or execution
  195. _enable_assertions = True
  196. _statement: Optional[ExecutableReturnsRows] = None
  197. session: Session
  198. dispatch: dispatcher[Query[_T]]
  199. # mirrors that of ClauseElement, used to propagate the "orm"
  200. # plugin as well as the "subject" of the plugin, e.g. the mapper
  201. # we are querying against.
  202. @util.memoized_property
  203. def _propagate_attrs(self) -> _PropagateAttrsType:
  204. return util.EMPTY_DICT
  205. def __init__(
  206. self,
  207. entities: Union[
  208. _ColumnsClauseArgument[Any], Sequence[_ColumnsClauseArgument[Any]]
  209. ],
  210. session: Optional[Session] = None,
  211. ):
  212. """Construct a :class:`_query.Query` directly.
  213. E.g.::
  214. q = Query([User, Address], session=some_session)
  215. The above is equivalent to::
  216. q = some_session.query(User, Address)
  217. :param entities: a sequence of entities and/or SQL expressions.
  218. :param session: a :class:`.Session` with which the
  219. :class:`_query.Query`
  220. will be associated. Optional; a :class:`_query.Query`
  221. can be associated
  222. with a :class:`.Session` generatively via the
  223. :meth:`_query.Query.with_session` method as well.
  224. .. seealso::
  225. :meth:`.Session.query`
  226. :meth:`_query.Query.with_session`
  227. """
  228. # session is usually present. There's one case in subqueryloader
  229. # where it stores a Query without a Session and also there are tests
  230. # for the query(Entity).with_session(session) API which is likely in
  231. # some old recipes, however these are legacy as select() can now be
  232. # used.
  233. self.session = session # type: ignore
  234. self._set_entities(entities)
  235. def _set_propagate_attrs(self, values: Mapping[str, Any]) -> Self:
  236. self._propagate_attrs = util.immutabledict(values)
  237. return self
  238. def _set_entities(
  239. self,
  240. entities: Union[
  241. _ColumnsClauseArgument[Any], Iterable[_ColumnsClauseArgument[Any]]
  242. ],
  243. ) -> None:
  244. self._raw_columns = [
  245. coercions.expect(
  246. roles.ColumnsClauseRole,
  247. ent,
  248. apply_propagate_attrs=self,
  249. post_inspect=True,
  250. )
  251. for ent in util.to_list(entities)
  252. ]
  253. def tuples(self: Query[_O]) -> Query[Tuple[_O]]:
  254. """return a tuple-typed form of this :class:`.Query`.
  255. This method invokes the :meth:`.Query.only_return_tuples`
  256. method with a value of ``True``, which by itself ensures that this
  257. :class:`.Query` will always return :class:`.Row` objects, even
  258. if the query is made against a single entity. It then also
  259. at the typing level will return a "typed" query, if possible,
  260. that will type result rows as ``Tuple`` objects with typed
  261. elements.
  262. This method can be compared to the :meth:`.Result.tuples` method,
  263. which returns "self", but from a typing perspective returns an object
  264. that will yield typed ``Tuple`` objects for results. Typing
  265. takes effect only if this :class:`.Query` object is a typed
  266. query object already.
  267. .. versionadded:: 2.0
  268. .. seealso::
  269. :meth:`.Result.tuples` - v2 equivalent method.
  270. """
  271. return self.only_return_tuples(True) # type: ignore
  272. def _entity_from_pre_ent_zero(self) -> Optional[_InternalEntityType[Any]]:
  273. if not self._raw_columns:
  274. return None
  275. ent = self._raw_columns[0]
  276. if "parententity" in ent._annotations:
  277. return ent._annotations["parententity"] # type: ignore
  278. elif "bundle" in ent._annotations:
  279. return ent._annotations["bundle"] # type: ignore
  280. else:
  281. # label, other SQL expression
  282. for element in visitors.iterate(ent):
  283. if "parententity" in element._annotations:
  284. return element._annotations["parententity"] # type: ignore # noqa: E501
  285. else:
  286. return None
  287. def _only_full_mapper_zero(self, methname: str) -> Mapper[Any]:
  288. if (
  289. len(self._raw_columns) != 1
  290. or "parententity" not in self._raw_columns[0]._annotations
  291. or not self._raw_columns[0].is_selectable
  292. ):
  293. raise sa_exc.InvalidRequestError(
  294. "%s() can only be used against "
  295. "a single mapped class." % methname
  296. )
  297. return self._raw_columns[0]._annotations["parententity"] # type: ignore # noqa: E501
  298. def _set_select_from(
  299. self, obj: Iterable[_FromClauseArgument], set_base_alias: bool
  300. ) -> None:
  301. fa = [
  302. coercions.expect(
  303. roles.StrictFromClauseRole,
  304. elem,
  305. allow_select=True,
  306. apply_propagate_attrs=self,
  307. )
  308. for elem in obj
  309. ]
  310. self._compile_options += {"_set_base_alias": set_base_alias}
  311. self._from_obj = tuple(fa)
  312. @_generative
  313. def _set_lazyload_from(self, state: InstanceState[Any]) -> Self:
  314. self.load_options += {"_lazy_loaded_from": state}
  315. return self
  316. def _get_condition(self) -> None:
  317. """used by legacy BakedQuery"""
  318. self._no_criterion_condition("get", order_by=False, distinct=False)
  319. def _get_existing_condition(self) -> None:
  320. self._no_criterion_assertion("get", order_by=False, distinct=False)
  321. def _no_criterion_assertion(
  322. self, meth: str, order_by: bool = True, distinct: bool = True
  323. ) -> None:
  324. if not self._enable_assertions:
  325. return
  326. if (
  327. self._where_criteria
  328. or self._statement is not None
  329. or self._from_obj
  330. or self._setup_joins
  331. or self._limit_clause is not None
  332. or self._offset_clause is not None
  333. or self._group_by_clauses
  334. or (order_by and self._order_by_clauses)
  335. or (distinct and self._distinct)
  336. ):
  337. raise sa_exc.InvalidRequestError(
  338. "Query.%s() being called on a "
  339. "Query with existing criterion. " % meth
  340. )
  341. def _no_criterion_condition(
  342. self, meth: str, order_by: bool = True, distinct: bool = True
  343. ) -> None:
  344. self._no_criterion_assertion(meth, order_by, distinct)
  345. self._from_obj = self._setup_joins = ()
  346. if self._statement is not None:
  347. self._compile_options += {"_statement": None}
  348. self._where_criteria = ()
  349. self._distinct = False
  350. self._order_by_clauses = self._group_by_clauses = ()
  351. def _no_clauseelement_condition(self, meth: str) -> None:
  352. if not self._enable_assertions:
  353. return
  354. if self._order_by_clauses:
  355. raise sa_exc.InvalidRequestError(
  356. "Query.%s() being called on a "
  357. "Query with existing criterion. " % meth
  358. )
  359. self._no_criterion_condition(meth)
  360. def _no_statement_condition(self, meth: str) -> None:
  361. if not self._enable_assertions:
  362. return
  363. if self._statement is not None:
  364. raise sa_exc.InvalidRequestError(
  365. (
  366. "Query.%s() being called on a Query with an existing full "
  367. "statement - can't apply criterion."
  368. )
  369. % meth
  370. )
  371. def _no_limit_offset(self, meth: str) -> None:
  372. if not self._enable_assertions:
  373. return
  374. if self._limit_clause is not None or self._offset_clause is not None:
  375. raise sa_exc.InvalidRequestError(
  376. "Query.%s() being called on a Query which already has LIMIT "
  377. "or OFFSET applied. Call %s() before limit() or offset() "
  378. "are applied." % (meth, meth)
  379. )
  380. @property
  381. def _has_row_limiting_clause(self) -> bool:
  382. return (
  383. self._limit_clause is not None or self._offset_clause is not None
  384. )
  385. def _get_options(
  386. self,
  387. populate_existing: Optional[bool] = None,
  388. version_check: Optional[bool] = None,
  389. only_load_props: Optional[Sequence[str]] = None,
  390. refresh_state: Optional[InstanceState[Any]] = None,
  391. identity_token: Optional[Any] = None,
  392. ) -> Self:
  393. load_options: Dict[str, Any] = {}
  394. compile_options: Dict[str, Any] = {}
  395. if version_check:
  396. load_options["_version_check"] = version_check
  397. if populate_existing:
  398. load_options["_populate_existing"] = populate_existing
  399. if refresh_state:
  400. load_options["_refresh_state"] = refresh_state
  401. compile_options["_for_refresh_state"] = True
  402. if only_load_props:
  403. compile_options["_only_load_props"] = frozenset(only_load_props)
  404. if identity_token:
  405. load_options["_identity_token"] = identity_token
  406. if load_options:
  407. self.load_options += load_options
  408. if compile_options:
  409. self._compile_options += compile_options
  410. return self
  411. def _clone(self, **kw: Any) -> Self:
  412. return self._generate()
  413. def _get_select_statement_only(self) -> Select[_T]:
  414. if self._statement is not None:
  415. raise sa_exc.InvalidRequestError(
  416. "Can't call this method on a Query that uses from_statement()"
  417. )
  418. return cast("Select[_T]", self.statement)
  419. @property
  420. def statement(self) -> Union[Select[_T], FromStatement[_T], UpdateBase]:
  421. """The full SELECT statement represented by this Query.
  422. The statement by default will not have disambiguating labels
  423. applied to the construct unless with_labels(True) is called
  424. first.
  425. """
  426. # .statement can return the direct future.Select() construct here, as
  427. # long as we are not using subsequent adaption features that
  428. # are made against raw entities, e.g. from_self(), with_polymorphic(),
  429. # select_entity_from(). If these features are being used, then
  430. # the Select() we return will not have the correct .selected_columns
  431. # collection and will not embed in subsequent queries correctly.
  432. # We could find a way to make this collection "correct", however
  433. # this would not be too different from doing the full compile as
  434. # we are doing in any case, the Select() would still not have the
  435. # proper state for other attributes like whereclause, order_by,
  436. # and these features are all deprecated in any case.
  437. #
  438. # for these reasons, Query is not a Select, it remains an ORM
  439. # object for which __clause_element__() must be called in order for
  440. # it to provide a real expression object.
  441. #
  442. # from there, it starts to look much like Query itself won't be
  443. # passed into the execute process and won't generate its own cache
  444. # key; this will all occur in terms of the ORM-enabled Select.
  445. stmt: Union[Select[_T], FromStatement[_T], UpdateBase]
  446. if not self._compile_options._set_base_alias:
  447. # if we don't have legacy top level aliasing features in use
  448. # then convert to a future select() directly
  449. stmt = self._statement_20(for_statement=True)
  450. else:
  451. stmt = self._compile_state(for_statement=True).statement
  452. if self._params:
  453. stmt = stmt.params(self._params)
  454. return stmt
  455. def _final_statement(self, legacy_query_style: bool = True) -> Select[Any]:
  456. """Return the 'final' SELECT statement for this :class:`.Query`.
  457. This is used by the testing suite only and is fairly inefficient.
  458. This is the Core-only select() that will be rendered by a complete
  459. compilation of this query, and is what .statement used to return
  460. in 1.3.
  461. """
  462. q = self._clone()
  463. return q._compile_state(
  464. use_legacy_query_style=legacy_query_style
  465. ).statement # type: ignore
  466. def _statement_20(
  467. self, for_statement: bool = False, use_legacy_query_style: bool = True
  468. ) -> Union[Select[_T], FromStatement[_T]]:
  469. # TODO: this event needs to be deprecated, as it currently applies
  470. # only to ORM query and occurs at this spot that is now more
  471. # or less an artificial spot
  472. if self.dispatch.before_compile:
  473. for fn in self.dispatch.before_compile:
  474. new_query = fn(self)
  475. if new_query is not None and new_query is not self:
  476. self = new_query
  477. if not fn._bake_ok: # type: ignore
  478. self._compile_options += {"_bake_ok": False}
  479. compile_options = self._compile_options
  480. compile_options += {
  481. "_for_statement": for_statement,
  482. "_use_legacy_query_style": use_legacy_query_style,
  483. }
  484. stmt: Union[Select[_T], FromStatement[_T]]
  485. if self._statement is not None:
  486. stmt = FromStatement(self._raw_columns, self._statement)
  487. stmt.__dict__.update(
  488. _with_options=self._with_options,
  489. _with_context_options=self._with_context_options,
  490. _compile_options=compile_options,
  491. _execution_options=self._execution_options,
  492. _propagate_attrs=self._propagate_attrs,
  493. )
  494. else:
  495. # Query / select() internal attributes are 99% cross-compatible
  496. stmt = Select._create_raw_select(**self.__dict__)
  497. stmt.__dict__.update(
  498. _label_style=self._label_style,
  499. _compile_options=compile_options,
  500. _propagate_attrs=self._propagate_attrs,
  501. )
  502. stmt.__dict__.pop("session", None)
  503. # ensure the ORM context is used to compile the statement, even
  504. # if it has no ORM entities. This is so ORM-only things like
  505. # _legacy_joins are picked up that wouldn't be picked up by the
  506. # Core statement context
  507. if "compile_state_plugin" not in stmt._propagate_attrs:
  508. stmt._propagate_attrs = stmt._propagate_attrs.union(
  509. {"compile_state_plugin": "orm", "plugin_subject": None}
  510. )
  511. return stmt
  512. def subquery(
  513. self,
  514. name: Optional[str] = None,
  515. with_labels: bool = False,
  516. reduce_columns: bool = False,
  517. ) -> Subquery:
  518. """Return the full SELECT statement represented by
  519. this :class:`_query.Query`, embedded within an
  520. :class:`_expression.Alias`.
  521. Eager JOIN generation within the query is disabled.
  522. .. seealso::
  523. :meth:`_sql.Select.subquery` - v2 comparable method.
  524. :param name: string name to be assigned as the alias;
  525. this is passed through to :meth:`_expression.FromClause.alias`.
  526. If ``None``, a name will be deterministically generated
  527. at compile time.
  528. :param with_labels: if True, :meth:`.with_labels` will be called
  529. on the :class:`_query.Query` first to apply table-qualified labels
  530. to all columns.
  531. :param reduce_columns: if True,
  532. :meth:`_expression.Select.reduce_columns` will
  533. be called on the resulting :func:`_expression.select` construct,
  534. to remove same-named columns where one also refers to the other
  535. via foreign key or WHERE clause equivalence.
  536. """
  537. q = self.enable_eagerloads(False)
  538. if with_labels:
  539. q = q.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
  540. stmt = q._get_select_statement_only()
  541. if TYPE_CHECKING:
  542. assert isinstance(stmt, Select)
  543. if reduce_columns:
  544. stmt = stmt.reduce_columns()
  545. return stmt.subquery(name=name)
  546. def cte(
  547. self,
  548. name: Optional[str] = None,
  549. recursive: bool = False,
  550. nesting: bool = False,
  551. ) -> CTE:
  552. r"""Return the full SELECT statement represented by this
  553. :class:`_query.Query` represented as a common table expression (CTE).
  554. Parameters and usage are the same as those of the
  555. :meth:`_expression.SelectBase.cte` method; see that method for
  556. further details.
  557. Here is the `PostgreSQL WITH
  558. RECURSIVE example
  559. <https://www.postgresql.org/docs/current/static/queries-with.html>`_.
  560. Note that, in this example, the ``included_parts`` cte and the
  561. ``incl_alias`` alias of it are Core selectables, which
  562. means the columns are accessed via the ``.c.`` attribute. The
  563. ``parts_alias`` object is an :func:`_orm.aliased` instance of the
  564. ``Part`` entity, so column-mapped attributes are available
  565. directly::
  566. from sqlalchemy.orm import aliased
  567. class Part(Base):
  568. __tablename__ = "part"
  569. part = Column(String, primary_key=True)
  570. sub_part = Column(String, primary_key=True)
  571. quantity = Column(Integer)
  572. included_parts = (
  573. session.query(Part.sub_part, Part.part, Part.quantity)
  574. .filter(Part.part == "our part")
  575. .cte(name="included_parts", recursive=True)
  576. )
  577. incl_alias = aliased(included_parts, name="pr")
  578. parts_alias = aliased(Part, name="p")
  579. included_parts = included_parts.union_all(
  580. session.query(
  581. parts_alias.sub_part, parts_alias.part, parts_alias.quantity
  582. ).filter(parts_alias.part == incl_alias.c.sub_part)
  583. )
  584. q = session.query(
  585. included_parts.c.sub_part,
  586. func.sum(included_parts.c.quantity).label("total_quantity"),
  587. ).group_by(included_parts.c.sub_part)
  588. .. seealso::
  589. :meth:`_sql.Select.cte` - v2 equivalent method.
  590. """ # noqa: E501
  591. return (
  592. self.enable_eagerloads(False)
  593. ._get_select_statement_only()
  594. .cte(name=name, recursive=recursive, nesting=nesting)
  595. )
  596. def label(self, name: Optional[str]) -> Label[Any]:
  597. """Return the full SELECT statement represented by this
  598. :class:`_query.Query`, converted
  599. to a scalar subquery with a label of the given name.
  600. .. seealso::
  601. :meth:`_sql.Select.label` - v2 comparable method.
  602. """
  603. return (
  604. self.enable_eagerloads(False)
  605. ._get_select_statement_only()
  606. .label(name)
  607. )
  608. @overload
  609. def as_scalar( # type: ignore[overload-overlap]
  610. self: Query[Tuple[_MAYBE_ENTITY]],
  611. ) -> ScalarSelect[_MAYBE_ENTITY]: ...
  612. @overload
  613. def as_scalar(
  614. self: Query[Tuple[_NOT_ENTITY]],
  615. ) -> ScalarSelect[_NOT_ENTITY]: ...
  616. @overload
  617. def as_scalar(self) -> ScalarSelect[Any]: ...
  618. @util.deprecated(
  619. "1.4",
  620. "The :meth:`_query.Query.as_scalar` method is deprecated and will be "
  621. "removed in a future release. Please refer to "
  622. ":meth:`_query.Query.scalar_subquery`.",
  623. )
  624. def as_scalar(self) -> ScalarSelect[Any]:
  625. """Return the full SELECT statement represented by this
  626. :class:`_query.Query`, converted to a scalar subquery.
  627. """
  628. return self.scalar_subquery()
  629. @overload
  630. def scalar_subquery(
  631. self: Query[Tuple[_MAYBE_ENTITY]],
  632. ) -> ScalarSelect[Any]: ...
  633. @overload
  634. def scalar_subquery(
  635. self: Query[Tuple[_NOT_ENTITY]],
  636. ) -> ScalarSelect[_NOT_ENTITY]: ...
  637. @overload
  638. def scalar_subquery(self) -> ScalarSelect[Any]: ...
  639. def scalar_subquery(self) -> ScalarSelect[Any]:
  640. """Return the full SELECT statement represented by this
  641. :class:`_query.Query`, converted to a scalar subquery.
  642. Analogous to
  643. :meth:`sqlalchemy.sql.expression.SelectBase.scalar_subquery`.
  644. .. versionchanged:: 1.4 The :meth:`_query.Query.scalar_subquery`
  645. method replaces the :meth:`_query.Query.as_scalar` method.
  646. .. seealso::
  647. :meth:`_sql.Select.scalar_subquery` - v2 comparable method.
  648. """
  649. return (
  650. self.enable_eagerloads(False)
  651. ._get_select_statement_only()
  652. .scalar_subquery()
  653. )
  654. @property
  655. def selectable(self) -> Union[Select[_T], FromStatement[_T], UpdateBase]:
  656. """Return the :class:`_expression.Select` object emitted by this
  657. :class:`_query.Query`.
  658. Used for :func:`_sa.inspect` compatibility, this is equivalent to::
  659. query.enable_eagerloads(False).with_labels().statement
  660. """
  661. return self.__clause_element__()
  662. def __clause_element__(
  663. self,
  664. ) -> Union[Select[_T], FromStatement[_T], UpdateBase]:
  665. return (
  666. self._with_compile_options(
  667. _enable_eagerloads=False, _render_for_subquery=True
  668. )
  669. .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
  670. .statement
  671. )
  672. @overload
  673. def only_return_tuples(
  674. self: Query[_O], value: Literal[True]
  675. ) -> RowReturningQuery[Tuple[_O]]: ...
  676. @overload
  677. def only_return_tuples(
  678. self: Query[_O], value: Literal[False]
  679. ) -> Query[_O]: ...
  680. @_generative
  681. def only_return_tuples(self, value: bool) -> Query[Any]:
  682. """When set to True, the query results will always be a
  683. :class:`.Row` object.
  684. This can change a query that normally returns a single entity
  685. as a scalar to return a :class:`.Row` result in all cases.
  686. .. seealso::
  687. :meth:`.Query.tuples` - returns tuples, but also at the typing
  688. level will type results as ``Tuple``.
  689. :meth:`_query.Query.is_single_entity`
  690. :meth:`_engine.Result.tuples` - v2 comparable method.
  691. """
  692. self.load_options += dict(_only_return_tuples=value)
  693. return self
  694. @property
  695. def is_single_entity(self) -> bool:
  696. """Indicates if this :class:`_query.Query`
  697. returns tuples or single entities.
  698. Returns True if this query returns a single entity for each instance
  699. in its result list, and False if this query returns a tuple of entities
  700. for each result.
  701. .. versionadded:: 1.3.11
  702. .. seealso::
  703. :meth:`_query.Query.only_return_tuples`
  704. """
  705. return (
  706. not self.load_options._only_return_tuples
  707. and len(self._raw_columns) == 1
  708. and "parententity" in self._raw_columns[0]._annotations
  709. and isinstance(
  710. self._raw_columns[0]._annotations["parententity"],
  711. ORMColumnsClauseRole,
  712. )
  713. )
  714. @_generative
  715. def enable_eagerloads(self, value: bool) -> Self:
  716. """Control whether or not eager joins and subqueries are
  717. rendered.
  718. When set to False, the returned Query will not render
  719. eager joins regardless of :func:`~sqlalchemy.orm.joinedload`,
  720. :func:`~sqlalchemy.orm.subqueryload` options
  721. or mapper-level ``lazy='joined'``/``lazy='subquery'``
  722. configurations.
  723. This is used primarily when nesting the Query's
  724. statement into a subquery or other
  725. selectable, or when using :meth:`_query.Query.yield_per`.
  726. """
  727. self._compile_options += {"_enable_eagerloads": value}
  728. return self
  729. @_generative
  730. def _with_compile_options(self, **opt: Any) -> Self:
  731. self._compile_options += opt
  732. return self
  733. @util.became_legacy_20(
  734. ":meth:`_orm.Query.with_labels` and :meth:`_orm.Query.apply_labels`",
  735. alternative="Use set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) "
  736. "instead.",
  737. )
  738. def with_labels(self) -> Self:
  739. return self.set_label_style(
  740. SelectLabelStyle.LABEL_STYLE_TABLENAME_PLUS_COL
  741. )
  742. apply_labels = with_labels
  743. @property
  744. def get_label_style(self) -> SelectLabelStyle:
  745. """
  746. Retrieve the current label style.
  747. .. versionadded:: 1.4
  748. .. seealso::
  749. :meth:`_sql.Select.get_label_style` - v2 equivalent method.
  750. """
  751. return self._label_style
  752. def set_label_style(self, style: SelectLabelStyle) -> Self:
  753. """Apply column labels to the return value of Query.statement.
  754. Indicates that this Query's `statement` accessor should return
  755. a SELECT statement that applies labels to all columns in the
  756. form <tablename>_<columnname>; this is commonly used to
  757. disambiguate columns from multiple tables which have the same
  758. name.
  759. When the `Query` actually issues SQL to load rows, it always
  760. uses column labeling.
  761. .. note:: The :meth:`_query.Query.set_label_style` method *only* applies
  762. the output of :attr:`_query.Query.statement`, and *not* to any of
  763. the result-row invoking systems of :class:`_query.Query` itself,
  764. e.g.
  765. :meth:`_query.Query.first`, :meth:`_query.Query.all`, etc.
  766. To execute
  767. a query using :meth:`_query.Query.set_label_style`, invoke the
  768. :attr:`_query.Query.statement` using :meth:`.Session.execute`::
  769. result = session.execute(
  770. query.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL).statement
  771. )
  772. .. versionadded:: 1.4
  773. .. seealso::
  774. :meth:`_sql.Select.set_label_style` - v2 equivalent method.
  775. """ # noqa
  776. if self._label_style is not style:
  777. self = self._generate()
  778. self._label_style = style
  779. return self
  780. @_generative
  781. def enable_assertions(self, value: bool) -> Self:
  782. """Control whether assertions are generated.
  783. When set to False, the returned Query will
  784. not assert its state before certain operations,
  785. including that LIMIT/OFFSET has not been applied
  786. when filter() is called, no criterion exists
  787. when get() is called, and no "from_statement()"
  788. exists when filter()/order_by()/group_by() etc.
  789. is called. This more permissive mode is used by
  790. custom Query subclasses to specify criterion or
  791. other modifiers outside of the usual usage patterns.
  792. Care should be taken to ensure that the usage
  793. pattern is even possible. A statement applied
  794. by from_statement() will override any criterion
  795. set by filter() or order_by(), for example.
  796. """
  797. self._enable_assertions = value
  798. return self
  799. @property
  800. def whereclause(self) -> Optional[ColumnElement[bool]]:
  801. """A readonly attribute which returns the current WHERE criterion for
  802. this Query.
  803. This returned value is a SQL expression construct, or ``None`` if no
  804. criterion has been established.
  805. .. seealso::
  806. :attr:`_sql.Select.whereclause` - v2 equivalent property.
  807. """
  808. return BooleanClauseList._construct_for_whereclause(
  809. self._where_criteria
  810. )
  811. @_generative
  812. def _with_current_path(self, path: PathRegistry) -> Self:
  813. """indicate that this query applies to objects loaded
  814. within a certain path.
  815. Used by deferred loaders (see strategies.py) which transfer
  816. query options from an originating query to a newly generated
  817. query intended for the deferred load.
  818. """
  819. self._compile_options += {"_current_path": path}
  820. return self
  821. @_generative
  822. def yield_per(self, count: int) -> Self:
  823. r"""Yield only ``count`` rows at a time.
  824. The purpose of this method is when fetching very large result sets
  825. (> 10K rows), to batch results in sub-collections and yield them
  826. out partially, so that the Python interpreter doesn't need to declare
  827. very large areas of memory which is both time consuming and leads
  828. to excessive memory use. The performance from fetching hundreds of
  829. thousands of rows can often double when a suitable yield-per setting
  830. (e.g. approximately 1000) is used, even with DBAPIs that buffer
  831. rows (which are most).
  832. As of SQLAlchemy 1.4, the :meth:`_orm.Query.yield_per` method is
  833. equivalent to using the ``yield_per`` execution option at the ORM
  834. level. See the section :ref:`orm_queryguide_yield_per` for further
  835. background on this option.
  836. .. seealso::
  837. :ref:`orm_queryguide_yield_per`
  838. """
  839. self.load_options += {"_yield_per": count}
  840. return self
  841. @util.became_legacy_20(
  842. ":meth:`_orm.Query.get`",
  843. alternative="The method is now available as :meth:`_orm.Session.get`",
  844. )
  845. def get(self, ident: _PKIdentityArgument) -> Optional[Any]:
  846. """Return an instance based on the given primary key identifier,
  847. or ``None`` if not found.
  848. E.g.::
  849. my_user = session.query(User).get(5)
  850. some_object = session.query(VersionedFoo).get((5, 10))
  851. some_object = session.query(VersionedFoo).get({"id": 5, "version_id": 10})
  852. :meth:`_query.Query.get` is special in that it provides direct
  853. access to the identity map of the owning :class:`.Session`.
  854. If the given primary key identifier is present
  855. in the local identity map, the object is returned
  856. directly from this collection and no SQL is emitted,
  857. unless the object has been marked fully expired.
  858. If not present,
  859. a SELECT is performed in order to locate the object.
  860. :meth:`_query.Query.get` also will perform a check if
  861. the object is present in the identity map and
  862. marked as expired - a SELECT
  863. is emitted to refresh the object as well as to
  864. ensure that the row is still present.
  865. If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.
  866. :meth:`_query.Query.get` is only used to return a single
  867. mapped instance, not multiple instances or
  868. individual column constructs, and strictly
  869. on a single primary key value. The originating
  870. :class:`_query.Query` must be constructed in this way,
  871. i.e. against a single mapped entity,
  872. with no additional filtering criterion. Loading
  873. options via :meth:`_query.Query.options` may be applied
  874. however, and will be used if the object is not
  875. yet locally present.
  876. :param ident: A scalar, tuple, or dictionary representing the
  877. primary key. For a composite (e.g. multiple column) primary key,
  878. a tuple or dictionary should be passed.
  879. For a single-column primary key, the scalar calling form is typically
  880. the most expedient. If the primary key of a row is the value "5",
  881. the call looks like::
  882. my_object = query.get(5)
  883. The tuple form contains primary key values typically in
  884. the order in which they correspond to the mapped
  885. :class:`_schema.Table`
  886. object's primary key columns, or if the
  887. :paramref:`_orm.Mapper.primary_key` configuration parameter were
  888. used, in
  889. the order used for that parameter. For example, if the primary key
  890. of a row is represented by the integer
  891. digits "5, 10" the call would look like::
  892. my_object = query.get((5, 10))
  893. The dictionary form should include as keys the mapped attribute names
  894. corresponding to each element of the primary key. If the mapped class
  895. has the attributes ``id``, ``version_id`` as the attributes which
  896. store the object's primary key value, the call would look like::
  897. my_object = query.get({"id": 5, "version_id": 10})
  898. .. versionadded:: 1.3 the :meth:`_query.Query.get`
  899. method now optionally
  900. accepts a dictionary of attribute names to values in order to
  901. indicate a primary key identifier.
  902. :return: The object instance, or ``None``.
  903. """ # noqa: E501
  904. self._no_criterion_assertion("get", order_by=False, distinct=False)
  905. # we still implement _get_impl() so that baked query can override
  906. # it
  907. return self._get_impl(ident, loading.load_on_pk_identity)
  908. def _get_impl(
  909. self,
  910. primary_key_identity: _PKIdentityArgument,
  911. db_load_fn: Callable[..., Any],
  912. identity_token: Optional[Any] = None,
  913. ) -> Optional[Any]:
  914. mapper = self._only_full_mapper_zero("get")
  915. return self.session._get_impl(
  916. mapper,
  917. primary_key_identity,
  918. db_load_fn,
  919. populate_existing=self.load_options._populate_existing,
  920. with_for_update=self._for_update_arg,
  921. options=self._with_options,
  922. identity_token=identity_token,
  923. execution_options=self._execution_options,
  924. )
  925. @property
  926. def lazy_loaded_from(self) -> Optional[InstanceState[Any]]:
  927. """An :class:`.InstanceState` that is using this :class:`_query.Query`
  928. for a lazy load operation.
  929. .. deprecated:: 1.4 This attribute should be viewed via the
  930. :attr:`.ORMExecuteState.lazy_loaded_from` attribute, within
  931. the context of the :meth:`.SessionEvents.do_orm_execute`
  932. event.
  933. .. seealso::
  934. :attr:`.ORMExecuteState.lazy_loaded_from`
  935. """
  936. return self.load_options._lazy_loaded_from # type: ignore
  937. @property
  938. def _current_path(self) -> PathRegistry:
  939. return self._compile_options._current_path # type: ignore
  940. @_generative
  941. def correlate(
  942. self,
  943. *fromclauses: Union[Literal[None, False], _FromClauseArgument],
  944. ) -> Self:
  945. """Return a :class:`.Query` construct which will correlate the given
  946. FROM clauses to that of an enclosing :class:`.Query` or
  947. :func:`~.expression.select`.
  948. The method here accepts mapped classes, :func:`.aliased` constructs,
  949. and :class:`_orm.Mapper` constructs as arguments, which are resolved
  950. into expression constructs, in addition to appropriate expression
  951. constructs.
  952. The correlation arguments are ultimately passed to
  953. :meth:`_expression.Select.correlate`
  954. after coercion to expression constructs.
  955. The correlation arguments take effect in such cases
  956. as when :meth:`_query.Query.from_self` is used, or when
  957. a subquery as returned by :meth:`_query.Query.subquery` is
  958. embedded in another :func:`_expression.select` construct.
  959. .. seealso::
  960. :meth:`_sql.Select.correlate` - v2 equivalent method.
  961. """
  962. self._auto_correlate = False
  963. if fromclauses and fromclauses[0] in {None, False}:
  964. self._correlate = ()
  965. else:
  966. self._correlate = self._correlate + tuple(
  967. coercions.expect(roles.FromClauseRole, f) for f in fromclauses
  968. )
  969. return self
  970. @_generative
  971. def autoflush(self, setting: bool) -> Self:
  972. """Return a Query with a specific 'autoflush' setting.
  973. As of SQLAlchemy 1.4, the :meth:`_orm.Query.autoflush` method
  974. is equivalent to using the ``autoflush`` execution option at the
  975. ORM level. See the section :ref:`orm_queryguide_autoflush` for
  976. further background on this option.
  977. """
  978. self.load_options += {"_autoflush": setting}
  979. return self
  980. @_generative
  981. def populate_existing(self) -> Self:
  982. """Return a :class:`_query.Query`
  983. that will expire and refresh all instances
  984. as they are loaded, or reused from the current :class:`.Session`.
  985. As of SQLAlchemy 1.4, the :meth:`_orm.Query.populate_existing` method
  986. is equivalent to using the ``populate_existing`` execution option at
  987. the ORM level. See the section :ref:`orm_queryguide_populate_existing`
  988. for further background on this option.
  989. """
  990. self.load_options += {"_populate_existing": True}
  991. return self
  992. @_generative
  993. def _with_invoke_all_eagers(self, value: bool) -> Self:
  994. """Set the 'invoke all eagers' flag which causes joined- and
  995. subquery loaders to traverse into already-loaded related objects
  996. and collections.
  997. Default is that of :attr:`_query.Query._invoke_all_eagers`.
  998. """
  999. self.load_options += {"_invoke_all_eagers": value}
  1000. return self
  1001. @util.became_legacy_20(
  1002. ":meth:`_orm.Query.with_parent`",
  1003. alternative="Use the :func:`_orm.with_parent` standalone construct.",
  1004. )
  1005. @util.preload_module("sqlalchemy.orm.relationships")
  1006. def with_parent(
  1007. self,
  1008. instance: object,
  1009. property: Optional[ # noqa: A002
  1010. attributes.QueryableAttribute[Any]
  1011. ] = None,
  1012. from_entity: Optional[_ExternalEntityType[Any]] = None,
  1013. ) -> Self:
  1014. """Add filtering criterion that relates the given instance
  1015. to a child object or collection, using its attribute state
  1016. as well as an established :func:`_orm.relationship()`
  1017. configuration.
  1018. The method uses the :func:`.with_parent` function to generate
  1019. the clause, the result of which is passed to
  1020. :meth:`_query.Query.filter`.
  1021. Parameters are the same as :func:`.with_parent`, with the exception
  1022. that the given property can be None, in which case a search is
  1023. performed against this :class:`_query.Query` object's target mapper.
  1024. :param instance:
  1025. An instance which has some :func:`_orm.relationship`.
  1026. :param property:
  1027. Class bound attribute which indicates
  1028. what relationship from the instance should be used to reconcile the
  1029. parent/child relationship.
  1030. :param from_entity:
  1031. Entity in which to consider as the left side. This defaults to the
  1032. "zero" entity of the :class:`_query.Query` itself.
  1033. """
  1034. relationships = util.preloaded.orm_relationships
  1035. if from_entity:
  1036. entity_zero = inspect(from_entity)
  1037. else:
  1038. entity_zero = _legacy_filter_by_entity_zero(self)
  1039. if property is None:
  1040. # TODO: deprecate, property has to be supplied
  1041. mapper = object_mapper(instance)
  1042. for prop in mapper.iterate_properties:
  1043. if (
  1044. isinstance(prop, relationships.RelationshipProperty)
  1045. and prop.mapper is entity_zero.mapper # type: ignore
  1046. ):
  1047. property = prop # type: ignore # noqa: A001
  1048. break
  1049. else:
  1050. raise sa_exc.InvalidRequestError(
  1051. "Could not locate a property which relates instances "
  1052. "of class '%s' to instances of class '%s'"
  1053. % (
  1054. entity_zero.mapper.class_.__name__, # type: ignore
  1055. instance.__class__.__name__,
  1056. )
  1057. )
  1058. return self.filter(
  1059. with_parent(
  1060. instance,
  1061. property, # type: ignore
  1062. entity_zero.entity, # type: ignore
  1063. )
  1064. )
  1065. @_generative
  1066. def add_entity(
  1067. self,
  1068. entity: _EntityType[Any],
  1069. alias: Optional[Union[Alias, Subquery]] = None,
  1070. ) -> Query[Any]:
  1071. """add a mapped entity to the list of result columns
  1072. to be returned.
  1073. .. seealso::
  1074. :meth:`_sql.Select.add_columns` - v2 comparable method.
  1075. """
  1076. if alias is not None:
  1077. # TODO: deprecate
  1078. entity = AliasedClass(entity, alias)
  1079. self._raw_columns = list(self._raw_columns)
  1080. self._raw_columns.append(
  1081. coercions.expect(
  1082. roles.ColumnsClauseRole, entity, apply_propagate_attrs=self
  1083. )
  1084. )
  1085. return self
  1086. @_generative
  1087. def with_session(self, session: Session) -> Self:
  1088. """Return a :class:`_query.Query` that will use the given
  1089. :class:`.Session`.
  1090. While the :class:`_query.Query`
  1091. object is normally instantiated using the
  1092. :meth:`.Session.query` method, it is legal to build the
  1093. :class:`_query.Query`
  1094. directly without necessarily using a :class:`.Session`. Such a
  1095. :class:`_query.Query` object, or any :class:`_query.Query`
  1096. already associated
  1097. with a different :class:`.Session`, can produce a new
  1098. :class:`_query.Query`
  1099. object associated with a target session using this method::
  1100. from sqlalchemy.orm import Query
  1101. query = Query([MyClass]).filter(MyClass.id == 5)
  1102. result = query.with_session(my_session).one()
  1103. """
  1104. self.session = session
  1105. return self
  1106. def _legacy_from_self(
  1107. self, *entities: _ColumnsClauseArgument[Any]
  1108. ) -> Self:
  1109. # used for query.count() as well as for the same
  1110. # function in BakedQuery, as well as some old tests in test_baked.py.
  1111. fromclause = (
  1112. self.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
  1113. .correlate(None)
  1114. .subquery()
  1115. ._anonymous_fromclause()
  1116. )
  1117. q = self._from_selectable(fromclause)
  1118. if entities:
  1119. q._set_entities(entities)
  1120. return q
  1121. @_generative
  1122. def _set_enable_single_crit(self, val: bool) -> Self:
  1123. self._compile_options += {"_enable_single_crit": val}
  1124. return self
  1125. @_generative
  1126. def _from_selectable(
  1127. self, fromclause: FromClause, set_entity_from: bool = True
  1128. ) -> Self:
  1129. for attr in (
  1130. "_where_criteria",
  1131. "_order_by_clauses",
  1132. "_group_by_clauses",
  1133. "_limit_clause",
  1134. "_offset_clause",
  1135. "_last_joined_entity",
  1136. "_setup_joins",
  1137. "_memoized_select_entities",
  1138. "_distinct",
  1139. "_distinct_on",
  1140. "_having_criteria",
  1141. "_prefixes",
  1142. "_suffixes",
  1143. ):
  1144. self.__dict__.pop(attr, None)
  1145. self._set_select_from([fromclause], set_entity_from)
  1146. self._compile_options += {
  1147. "_enable_single_crit": False,
  1148. }
  1149. return self
  1150. @util.deprecated(
  1151. "1.4",
  1152. ":meth:`_query.Query.values` "
  1153. "is deprecated and will be removed in a "
  1154. "future release. Please use :meth:`_query.Query.with_entities`",
  1155. )
  1156. def values(self, *columns: _ColumnsClauseArgument[Any]) -> Iterable[Any]:
  1157. """Return an iterator yielding result tuples corresponding
  1158. to the given list of columns
  1159. """
  1160. return self._values_no_warn(*columns)
  1161. _values = values
  1162. def _values_no_warn(
  1163. self, *columns: _ColumnsClauseArgument[Any]
  1164. ) -> Iterable[Any]:
  1165. if not columns:
  1166. return iter(())
  1167. q = self._clone().enable_eagerloads(False)
  1168. q._set_entities(columns)
  1169. if not q.load_options._yield_per:
  1170. q.load_options += {"_yield_per": 10}
  1171. return iter(q)
  1172. @util.deprecated(
  1173. "1.4",
  1174. ":meth:`_query.Query.value` "
  1175. "is deprecated and will be removed in a "
  1176. "future release. Please use :meth:`_query.Query.with_entities` "
  1177. "in combination with :meth:`_query.Query.scalar`",
  1178. )
  1179. def value(self, column: _ColumnExpressionArgument[Any]) -> Any:
  1180. """Return a scalar result corresponding to the given
  1181. column expression.
  1182. """
  1183. try:
  1184. return next(self._values_no_warn(column))[0] # type: ignore
  1185. except StopIteration:
  1186. return None
  1187. @overload
  1188. def with_entities(self, _entity: _EntityType[_O]) -> Query[_O]: ...
  1189. @overload
  1190. def with_entities(
  1191. self,
  1192. _colexpr: roles.TypedColumnsClauseRole[_T],
  1193. ) -> RowReturningQuery[Tuple[_T]]: ...
  1194. # START OVERLOADED FUNCTIONS self.with_entities RowReturningQuery 2-8
  1195. # code within this block is **programmatically,
  1196. # statically generated** by tools/generate_tuple_map_overloads.py
  1197. @overload
  1198. def with_entities(
  1199. self, __ent0: _TCCA[_T0], __ent1: _TCCA[_T1]
  1200. ) -> RowReturningQuery[Tuple[_T0, _T1]]: ...
  1201. @overload
  1202. def with_entities(
  1203. self, __ent0: _TCCA[_T0], __ent1: _TCCA[_T1], __ent2: _TCCA[_T2]
  1204. ) -> RowReturningQuery[Tuple[_T0, _T1, _T2]]: ...
  1205. @overload
  1206. def with_entities(
  1207. self,
  1208. __ent0: _TCCA[_T0],
  1209. __ent1: _TCCA[_T1],
  1210. __ent2: _TCCA[_T2],
  1211. __ent3: _TCCA[_T3],
  1212. ) -> RowReturningQuery[Tuple[_T0, _T1, _T2, _T3]]: ...
  1213. @overload
  1214. def with_entities(
  1215. self,
  1216. __ent0: _TCCA[_T0],
  1217. __ent1: _TCCA[_T1],
  1218. __ent2: _TCCA[_T2],
  1219. __ent3: _TCCA[_T3],
  1220. __ent4: _TCCA[_T4],
  1221. ) -> RowReturningQuery[Tuple[_T0, _T1, _T2, _T3, _T4]]: ...
  1222. @overload
  1223. def with_entities(
  1224. self,
  1225. __ent0: _TCCA[_T0],
  1226. __ent1: _TCCA[_T1],
  1227. __ent2: _TCCA[_T2],
  1228. __ent3: _TCCA[_T3],
  1229. __ent4: _TCCA[_T4],
  1230. __ent5: _TCCA[_T5],
  1231. ) -> RowReturningQuery[Tuple[_T0, _T1, _T2, _T3, _T4, _T5]]: ...
  1232. @overload
  1233. def with_entities(
  1234. self,
  1235. __ent0: _TCCA[_T0],
  1236. __ent1: _TCCA[_T1],
  1237. __ent2: _TCCA[_T2],
  1238. __ent3: _TCCA[_T3],
  1239. __ent4: _TCCA[_T4],
  1240. __ent5: _TCCA[_T5],
  1241. __ent6: _TCCA[_T6],
  1242. ) -> RowReturningQuery[Tuple[_T0, _T1, _T2, _T3, _T4, _T5, _T6]]: ...
  1243. @overload
  1244. def with_entities(
  1245. self,
  1246. __ent0: _TCCA[_T0],
  1247. __ent1: _TCCA[_T1],
  1248. __ent2: _TCCA[_T2],
  1249. __ent3: _TCCA[_T3],
  1250. __ent4: _TCCA[_T4],
  1251. __ent5: _TCCA[_T5],
  1252. __ent6: _TCCA[_T6],
  1253. __ent7: _TCCA[_T7],
  1254. ) -> RowReturningQuery[Tuple[_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7]]: ...
  1255. # END OVERLOADED FUNCTIONS self.with_entities
  1256. @overload
  1257. def with_entities(
  1258. self, *entities: _ColumnsClauseArgument[Any]
  1259. ) -> Query[Any]: ...
  1260. @_generative
  1261. def with_entities(
  1262. self, *entities: _ColumnsClauseArgument[Any], **__kw: Any
  1263. ) -> Query[Any]:
  1264. r"""Return a new :class:`_query.Query`
  1265. replacing the SELECT list with the
  1266. given entities.
  1267. e.g.::
  1268. # Users, filtered on some arbitrary criterion
  1269. # and then ordered by related email address
  1270. q = (
  1271. session.query(User)
  1272. .join(User.address)
  1273. .filter(User.name.like("%ed%"))
  1274. .order_by(Address.email)
  1275. )
  1276. # given *only* User.id==5, Address.email, and 'q', what
  1277. # would the *next* User in the result be ?
  1278. subq = (
  1279. q.with_entities(Address.email)
  1280. .order_by(None)
  1281. .filter(User.id == 5)
  1282. .subquery()
  1283. )
  1284. q = q.join((subq, subq.c.email < Address.email)).limit(1)
  1285. .. seealso::
  1286. :meth:`_sql.Select.with_only_columns` - v2 comparable method.
  1287. """
  1288. if __kw:
  1289. raise _no_kw()
  1290. # Query has all the same fields as Select for this operation
  1291. # this could in theory be based on a protocol but not sure if it's
  1292. # worth it
  1293. _MemoizedSelectEntities._generate_for_statement(self) # type: ignore
  1294. self._set_entities(entities)
  1295. return self
  1296. @_generative
  1297. def add_columns(
  1298. self, *column: _ColumnExpressionArgument[Any]
  1299. ) -> Query[Any]:
  1300. """Add one or more column expressions to the list
  1301. of result columns to be returned.
  1302. .. seealso::
  1303. :meth:`_sql.Select.add_columns` - v2 comparable method.
  1304. """
  1305. self._raw_columns = list(self._raw_columns)
  1306. self._raw_columns.extend(
  1307. coercions.expect(
  1308. roles.ColumnsClauseRole,
  1309. c,
  1310. apply_propagate_attrs=self,
  1311. post_inspect=True,
  1312. )
  1313. for c in column
  1314. )
  1315. return self
  1316. @util.deprecated(
  1317. "1.4",
  1318. ":meth:`_query.Query.add_column` "
  1319. "is deprecated and will be removed in a "
  1320. "future release. Please use :meth:`_query.Query.add_columns`",
  1321. )
  1322. def add_column(self, column: _ColumnExpressionArgument[Any]) -> Query[Any]:
  1323. """Add a column expression to the list of result columns to be
  1324. returned.
  1325. """
  1326. return self.add_columns(column)
  1327. @_generative
  1328. def options(self, *args: ExecutableOption) -> Self:
  1329. """Return a new :class:`_query.Query` object,
  1330. applying the given list of
  1331. mapper options.
  1332. Most supplied options regard changing how column- and
  1333. relationship-mapped attributes are loaded.
  1334. .. seealso::
  1335. :ref:`loading_columns`
  1336. :ref:`relationship_loader_options`
  1337. """
  1338. opts = tuple(util.flatten_iterator(args))
  1339. if self._compile_options._current_path:
  1340. # opting for lower method overhead for the checks
  1341. for opt in opts:
  1342. if not opt._is_core and opt._is_legacy_option: # type: ignore
  1343. opt.process_query_conditionally(self) # type: ignore
  1344. else:
  1345. for opt in opts:
  1346. if not opt._is_core and opt._is_legacy_option: # type: ignore
  1347. opt.process_query(self) # type: ignore
  1348. self._with_options += opts
  1349. return self
  1350. def with_transformation(
  1351. self, fn: Callable[[Query[Any]], Query[Any]]
  1352. ) -> Query[Any]:
  1353. """Return a new :class:`_query.Query` object transformed by
  1354. the given function.
  1355. E.g.::
  1356. def filter_something(criterion):
  1357. def transform(q):
  1358. return q.filter(criterion)
  1359. return transform
  1360. q = q.with_transformation(filter_something(x == 5))
  1361. This allows ad-hoc recipes to be created for :class:`_query.Query`
  1362. objects.
  1363. """
  1364. return fn(self)
  1365. def get_execution_options(self) -> _ImmutableExecuteOptions:
  1366. """Get the non-SQL options which will take effect during execution.
  1367. .. versionadded:: 1.3
  1368. .. seealso::
  1369. :meth:`_query.Query.execution_options`
  1370. :meth:`_sql.Select.get_execution_options` - v2 comparable method.
  1371. """
  1372. return self._execution_options
  1373. @overload
  1374. def execution_options(
  1375. self,
  1376. *,
  1377. compiled_cache: Optional[CompiledCacheType] = ...,
  1378. logging_token: str = ...,
  1379. isolation_level: IsolationLevel = ...,
  1380. no_parameters: bool = False,
  1381. stream_results: bool = False,
  1382. max_row_buffer: int = ...,
  1383. yield_per: int = ...,
  1384. insertmanyvalues_page_size: int = ...,
  1385. schema_translate_map: Optional[SchemaTranslateMapType] = ...,
  1386. populate_existing: bool = False,
  1387. autoflush: bool = False,
  1388. preserve_rowcount: bool = False,
  1389. **opt: Any,
  1390. ) -> Self: ...
  1391. @overload
  1392. def execution_options(self, **opt: Any) -> Self: ...
  1393. @_generative
  1394. def execution_options(self, **kwargs: Any) -> Self:
  1395. """Set non-SQL options which take effect during execution.
  1396. Options allowed here include all of those accepted by
  1397. :meth:`_engine.Connection.execution_options`, as well as a series
  1398. of ORM specific options:
  1399. ``populate_existing=True`` - equivalent to using
  1400. :meth:`_orm.Query.populate_existing`
  1401. ``autoflush=True|False`` - equivalent to using
  1402. :meth:`_orm.Query.autoflush`
  1403. ``yield_per=<value>`` - equivalent to using
  1404. :meth:`_orm.Query.yield_per`
  1405. Note that the ``stream_results`` execution option is enabled
  1406. automatically if the :meth:`~sqlalchemy.orm.query.Query.yield_per()`
  1407. method or execution option is used.
  1408. .. versionadded:: 1.4 - added ORM options to
  1409. :meth:`_orm.Query.execution_options`
  1410. The execution options may also be specified on a per execution basis
  1411. when using :term:`2.0 style` queries via the
  1412. :paramref:`_orm.Session.execution_options` parameter.
  1413. .. warning:: The
  1414. :paramref:`_engine.Connection.execution_options.stream_results`
  1415. parameter should not be used at the level of individual ORM
  1416. statement executions, as the :class:`_orm.Session` will not track
  1417. objects from different schema translate maps within a single
  1418. session. For multiple schema translate maps within the scope of a
  1419. single :class:`_orm.Session`, see :ref:`examples_sharding`.
  1420. .. seealso::
  1421. :ref:`engine_stream_results`
  1422. :meth:`_query.Query.get_execution_options`
  1423. :meth:`_sql.Select.execution_options` - v2 equivalent method.
  1424. """
  1425. self._execution_options = self._execution_options.union(kwargs)
  1426. return self
  1427. @_generative
  1428. def with_for_update(
  1429. self,
  1430. *,
  1431. nowait: bool = False,
  1432. read: bool = False,
  1433. of: Optional[_ForUpdateOfArgument] = None,
  1434. skip_locked: bool = False,
  1435. key_share: bool = False,
  1436. ) -> Self:
  1437. """return a new :class:`_query.Query`
  1438. with the specified options for the
  1439. ``FOR UPDATE`` clause.
  1440. The behavior of this method is identical to that of
  1441. :meth:`_expression.GenerativeSelect.with_for_update`.
  1442. When called with no arguments,
  1443. the resulting ``SELECT`` statement will have a ``FOR UPDATE`` clause
  1444. appended. When additional arguments are specified, backend-specific
  1445. options such as ``FOR UPDATE NOWAIT`` or ``LOCK IN SHARE MODE``
  1446. can take effect.
  1447. E.g.::
  1448. q = (
  1449. sess.query(User)
  1450. .populate_existing()
  1451. .with_for_update(nowait=True, of=User)
  1452. )
  1453. The above query on a PostgreSQL backend will render like:
  1454. .. sourcecode:: sql
  1455. SELECT users.id AS users_id FROM users FOR UPDATE OF users NOWAIT
  1456. .. warning::
  1457. Using ``with_for_update`` in the context of eager loading
  1458. relationships is not officially supported or recommended by
  1459. SQLAlchemy and may not work with certain queries on various
  1460. database backends. When ``with_for_update`` is successfully used
  1461. with a query that involves :func:`_orm.joinedload`, SQLAlchemy will
  1462. attempt to emit SQL that locks all involved tables.
  1463. .. note:: It is generally a good idea to combine the use of the
  1464. :meth:`_orm.Query.populate_existing` method when using the
  1465. :meth:`_orm.Query.with_for_update` method. The purpose of
  1466. :meth:`_orm.Query.populate_existing` is to force all the data read
  1467. from the SELECT to be populated into the ORM objects returned,
  1468. even if these objects are already in the :term:`identity map`.
  1469. .. seealso::
  1470. :meth:`_expression.GenerativeSelect.with_for_update`
  1471. - Core level method with
  1472. full argument and behavioral description.
  1473. :meth:`_orm.Query.populate_existing` - overwrites attributes of
  1474. objects already loaded in the identity map.
  1475. """ # noqa: E501
  1476. self._for_update_arg = ForUpdateArg(
  1477. read=read,
  1478. nowait=nowait,
  1479. of=of,
  1480. skip_locked=skip_locked,
  1481. key_share=key_share,
  1482. )
  1483. return self
  1484. @_generative
  1485. def params(
  1486. self, __params: Optional[Dict[str, Any]] = None, **kw: Any
  1487. ) -> Self:
  1488. r"""Add values for bind parameters which may have been
  1489. specified in filter().
  1490. Parameters may be specified using \**kwargs, or optionally a single
  1491. dictionary as the first positional argument. The reason for both is
  1492. that \**kwargs is convenient, however some parameter dictionaries
  1493. contain unicode keys in which case \**kwargs cannot be used.
  1494. """
  1495. if __params:
  1496. kw.update(__params)
  1497. self._params = self._params.union(kw)
  1498. return self
  1499. def where(self, *criterion: _ColumnExpressionArgument[bool]) -> Self:
  1500. """A synonym for :meth:`.Query.filter`.
  1501. .. versionadded:: 1.4
  1502. .. seealso::
  1503. :meth:`_sql.Select.where` - v2 equivalent method.
  1504. """
  1505. return self.filter(*criterion)
  1506. @_generative
  1507. @_assertions(_no_statement_condition, _no_limit_offset)
  1508. def filter(self, *criterion: _ColumnExpressionArgument[bool]) -> Self:
  1509. r"""Apply the given filtering criterion to a copy
  1510. of this :class:`_query.Query`, using SQL expressions.
  1511. e.g.::
  1512. session.query(MyClass).filter(MyClass.name == "some name")
  1513. Multiple criteria may be specified as comma separated; the effect
  1514. is that they will be joined together using the :func:`.and_`
  1515. function::
  1516. session.query(MyClass).filter(MyClass.name == "some name", MyClass.id > 5)
  1517. The criterion is any SQL expression object applicable to the
  1518. WHERE clause of a select. String expressions are coerced
  1519. into SQL expression constructs via the :func:`_expression.text`
  1520. construct.
  1521. .. seealso::
  1522. :meth:`_query.Query.filter_by` - filter on keyword expressions.
  1523. :meth:`_sql.Select.where` - v2 equivalent method.
  1524. """ # noqa: E501
  1525. for crit in list(criterion):
  1526. crit = coercions.expect(
  1527. roles.WhereHavingRole, crit, apply_propagate_attrs=self
  1528. )
  1529. self._where_criteria += (crit,)
  1530. return self
  1531. @util.memoized_property
  1532. def _last_joined_entity(
  1533. self,
  1534. ) -> Optional[Union[_InternalEntityType[Any], _JoinTargetElement]]:
  1535. if self._setup_joins:
  1536. return _determine_last_joined_entity(
  1537. self._setup_joins,
  1538. )
  1539. else:
  1540. return None
  1541. def _filter_by_zero(self) -> Any:
  1542. """for the filter_by() method, return the target entity for which
  1543. we will attempt to derive an expression from based on string name.
  1544. """
  1545. if self._setup_joins:
  1546. _last_joined_entity = self._last_joined_entity
  1547. if _last_joined_entity is not None:
  1548. return _last_joined_entity
  1549. # discussion related to #7239
  1550. # special check determines if we should try to derive attributes
  1551. # for filter_by() from the "from object", i.e., if the user
  1552. # called query.select_from(some selectable).filter_by(some_attr=value).
  1553. # We don't want to do that in the case that methods like
  1554. # from_self(), select_entity_from(), or a set op like union() were
  1555. # called; while these methods also place a
  1556. # selectable in the _from_obj collection, they also set up
  1557. # the _set_base_alias boolean which turns on the whole "adapt the
  1558. # entity to this selectable" thing, meaning the query still continues
  1559. # to construct itself in terms of the lead entity that was passed
  1560. # to query(), e.g. query(User).from_self() is still in terms of User,
  1561. # and not the subquery that from_self() created. This feature of
  1562. # "implicitly adapt all occurrences of entity X to some arbitrary
  1563. # subquery" is the main thing I am trying to do away with in 2.0 as
  1564. # users should now used aliased() for that, but I can't entirely get
  1565. # rid of it due to query.union() and other set ops relying upon it.
  1566. #
  1567. # compare this to the base Select()._filter_by_zero() which can
  1568. # just return self._from_obj[0] if present, because there is no
  1569. # "_set_base_alias" feature.
  1570. #
  1571. # IOW, this conditional essentially detects if
  1572. # "select_from(some_selectable)" has been called, as opposed to
  1573. # "select_entity_from()", "from_self()"
  1574. # or "union() / some_set_op()".
  1575. if self._from_obj and not self._compile_options._set_base_alias:
  1576. return self._from_obj[0]
  1577. return self._raw_columns[0]
  1578. def filter_by(self, **kwargs: Any) -> Self:
  1579. r"""Apply the given filtering criterion to a copy
  1580. of this :class:`_query.Query`, using keyword expressions.
  1581. e.g.::
  1582. session.query(MyClass).filter_by(name="some name")
  1583. Multiple criteria may be specified as comma separated; the effect
  1584. is that they will be joined together using the :func:`.and_`
  1585. function::
  1586. session.query(MyClass).filter_by(name="some name", id=5)
  1587. The keyword expressions are extracted from the primary
  1588. entity of the query, or the last entity that was the
  1589. target of a call to :meth:`_query.Query.join`.
  1590. .. seealso::
  1591. :meth:`_query.Query.filter` - filter on SQL expressions.
  1592. :meth:`_sql.Select.filter_by` - v2 comparable method.
  1593. """
  1594. from_entity = self._filter_by_zero()
  1595. clauses = [
  1596. _entity_namespace_key(from_entity, key) == value
  1597. for key, value in kwargs.items()
  1598. ]
  1599. return self.filter(*clauses)
  1600. @_generative
  1601. def order_by(
  1602. self,
  1603. __first: Union[
  1604. Literal[None, False, _NoArg.NO_ARG],
  1605. _ColumnExpressionOrStrLabelArgument[Any],
  1606. ] = _NoArg.NO_ARG,
  1607. *clauses: _ColumnExpressionOrStrLabelArgument[Any],
  1608. ) -> Self:
  1609. """Apply one or more ORDER BY criteria to the query and return
  1610. the newly resulting :class:`_query.Query`.
  1611. e.g.::
  1612. q = session.query(Entity).order_by(Entity.id, Entity.name)
  1613. Calling this method multiple times is equivalent to calling it once
  1614. with all the clauses concatenated. All existing ORDER BY criteria may
  1615. be cancelled by passing ``None`` by itself. New ORDER BY criteria may
  1616. then be added by invoking :meth:`_orm.Query.order_by` again, e.g.::
  1617. # will erase all ORDER BY and ORDER BY new_col alone
  1618. q = q.order_by(None).order_by(new_col)
  1619. .. seealso::
  1620. These sections describe ORDER BY in terms of :term:`2.0 style`
  1621. invocation but apply to :class:`_orm.Query` as well:
  1622. :ref:`tutorial_order_by` - in the :ref:`unified_tutorial`
  1623. :ref:`tutorial_order_by_label` - in the :ref:`unified_tutorial`
  1624. :meth:`_sql.Select.order_by` - v2 equivalent method.
  1625. """
  1626. for assertion in (self._no_statement_condition, self._no_limit_offset):
  1627. assertion("order_by")
  1628. if not clauses and (__first is None or __first is False):
  1629. self._order_by_clauses = ()
  1630. elif __first is not _NoArg.NO_ARG:
  1631. criterion = tuple(
  1632. coercions.expect(roles.OrderByRole, clause)
  1633. for clause in (__first,) + clauses
  1634. )
  1635. self._order_by_clauses += criterion
  1636. return self
  1637. @_generative
  1638. def group_by(
  1639. self,
  1640. __first: Union[
  1641. Literal[None, False, _NoArg.NO_ARG],
  1642. _ColumnExpressionOrStrLabelArgument[Any],
  1643. ] = _NoArg.NO_ARG,
  1644. *clauses: _ColumnExpressionOrStrLabelArgument[Any],
  1645. ) -> Self:
  1646. """Apply one or more GROUP BY criterion to the query and return
  1647. the newly resulting :class:`_query.Query`.
  1648. All existing GROUP BY settings can be suppressed by
  1649. passing ``None`` - this will suppress any GROUP BY configured
  1650. on mappers as well.
  1651. .. seealso::
  1652. These sections describe GROUP BY in terms of :term:`2.0 style`
  1653. invocation but apply to :class:`_orm.Query` as well:
  1654. :ref:`tutorial_group_by_w_aggregates` - in the
  1655. :ref:`unified_tutorial`
  1656. :ref:`tutorial_order_by_label` - in the :ref:`unified_tutorial`
  1657. :meth:`_sql.Select.group_by` - v2 equivalent method.
  1658. """
  1659. for assertion in (self._no_statement_condition, self._no_limit_offset):
  1660. assertion("group_by")
  1661. if not clauses and (__first is None or __first is False):
  1662. self._group_by_clauses = ()
  1663. elif __first is not _NoArg.NO_ARG:
  1664. criterion = tuple(
  1665. coercions.expect(roles.GroupByRole, clause)
  1666. for clause in (__first,) + clauses
  1667. )
  1668. self._group_by_clauses += criterion
  1669. return self
  1670. @_generative
  1671. @_assertions(_no_statement_condition, _no_limit_offset)
  1672. def having(self, *having: _ColumnExpressionArgument[bool]) -> Self:
  1673. r"""Apply a HAVING criterion to the query and return the
  1674. newly resulting :class:`_query.Query`.
  1675. :meth:`_query.Query.having` is used in conjunction with
  1676. :meth:`_query.Query.group_by`.
  1677. HAVING criterion makes it possible to use filters on aggregate
  1678. functions like COUNT, SUM, AVG, MAX, and MIN, eg.::
  1679. q = (
  1680. session.query(User.id)
  1681. .join(User.addresses)
  1682. .group_by(User.id)
  1683. .having(func.count(Address.id) > 2)
  1684. )
  1685. .. seealso::
  1686. :meth:`_sql.Select.having` - v2 equivalent method.
  1687. """
  1688. for criterion in having:
  1689. having_criteria = coercions.expect(
  1690. roles.WhereHavingRole, criterion
  1691. )
  1692. self._having_criteria += (having_criteria,)
  1693. return self
  1694. def _set_op(self, expr_fn: Any, *q: Query[Any]) -> Self:
  1695. list_of_queries = (self,) + q
  1696. return self._from_selectable(expr_fn(*(list_of_queries)).subquery())
  1697. def union(self, *q: Query[Any]) -> Self:
  1698. """Produce a UNION of this Query against one or more queries.
  1699. e.g.::
  1700. q1 = sess.query(SomeClass).filter(SomeClass.foo == "bar")
  1701. q2 = sess.query(SomeClass).filter(SomeClass.bar == "foo")
  1702. q3 = q1.union(q2)
  1703. The method accepts multiple Query objects so as to control
  1704. the level of nesting. A series of ``union()`` calls such as::
  1705. x.union(y).union(z).all()
  1706. will nest on each ``union()``, and produces:
  1707. .. sourcecode:: sql
  1708. SELECT * FROM (SELECT * FROM (SELECT * FROM X UNION
  1709. SELECT * FROM y) UNION SELECT * FROM Z)
  1710. Whereas::
  1711. x.union(y, z).all()
  1712. produces:
  1713. .. sourcecode:: sql
  1714. SELECT * FROM (SELECT * FROM X UNION SELECT * FROM y UNION
  1715. SELECT * FROM Z)
  1716. Note that many database backends do not allow ORDER BY to
  1717. be rendered on a query called within UNION, EXCEPT, etc.
  1718. To disable all ORDER BY clauses including those configured
  1719. on mappers, issue ``query.order_by(None)`` - the resulting
  1720. :class:`_query.Query` object will not render ORDER BY within
  1721. its SELECT statement.
  1722. .. seealso::
  1723. :meth:`_sql.Select.union` - v2 equivalent method.
  1724. """
  1725. return self._set_op(expression.union, *q)
  1726. def union_all(self, *q: Query[Any]) -> Self:
  1727. """Produce a UNION ALL of this Query against one or more queries.
  1728. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1729. that method for usage examples.
  1730. .. seealso::
  1731. :meth:`_sql.Select.union_all` - v2 equivalent method.
  1732. """
  1733. return self._set_op(expression.union_all, *q)
  1734. def intersect(self, *q: Query[Any]) -> Self:
  1735. """Produce an INTERSECT of this Query against one or more queries.
  1736. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1737. that method for usage examples.
  1738. .. seealso::
  1739. :meth:`_sql.Select.intersect` - v2 equivalent method.
  1740. """
  1741. return self._set_op(expression.intersect, *q)
  1742. def intersect_all(self, *q: Query[Any]) -> Self:
  1743. """Produce an INTERSECT ALL of this Query against one or more queries.
  1744. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1745. that method for usage examples.
  1746. .. seealso::
  1747. :meth:`_sql.Select.intersect_all` - v2 equivalent method.
  1748. """
  1749. return self._set_op(expression.intersect_all, *q)
  1750. def except_(self, *q: Query[Any]) -> Self:
  1751. """Produce an EXCEPT of this Query against one or more queries.
  1752. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1753. that method for usage examples.
  1754. .. seealso::
  1755. :meth:`_sql.Select.except_` - v2 equivalent method.
  1756. """
  1757. return self._set_op(expression.except_, *q)
  1758. def except_all(self, *q: Query[Any]) -> Self:
  1759. """Produce an EXCEPT ALL of this Query against one or more queries.
  1760. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1761. that method for usage examples.
  1762. .. seealso::
  1763. :meth:`_sql.Select.except_all` - v2 equivalent method.
  1764. """
  1765. return self._set_op(expression.except_all, *q)
  1766. @_generative
  1767. @_assertions(_no_statement_condition, _no_limit_offset)
  1768. def join(
  1769. self,
  1770. target: _JoinTargetArgument,
  1771. onclause: Optional[_OnClauseArgument] = None,
  1772. *,
  1773. isouter: bool = False,
  1774. full: bool = False,
  1775. ) -> Self:
  1776. r"""Create a SQL JOIN against this :class:`_query.Query`
  1777. object's criterion
  1778. and apply generatively, returning the newly resulting
  1779. :class:`_query.Query`.
  1780. **Simple Relationship Joins**
  1781. Consider a mapping between two classes ``User`` and ``Address``,
  1782. with a relationship ``User.addresses`` representing a collection
  1783. of ``Address`` objects associated with each ``User``. The most
  1784. common usage of :meth:`_query.Query.join`
  1785. is to create a JOIN along this
  1786. relationship, using the ``User.addresses`` attribute as an indicator
  1787. for how this should occur::
  1788. q = session.query(User).join(User.addresses)
  1789. Where above, the call to :meth:`_query.Query.join` along
  1790. ``User.addresses`` will result in SQL approximately equivalent to:
  1791. .. sourcecode:: sql
  1792. SELECT user.id, user.name
  1793. FROM user JOIN address ON user.id = address.user_id
  1794. In the above example we refer to ``User.addresses`` as passed to
  1795. :meth:`_query.Query.join` as the "on clause", that is, it indicates
  1796. how the "ON" portion of the JOIN should be constructed.
  1797. To construct a chain of joins, multiple :meth:`_query.Query.join`
  1798. calls may be used. The relationship-bound attribute implies both
  1799. the left and right side of the join at once::
  1800. q = (
  1801. session.query(User)
  1802. .join(User.orders)
  1803. .join(Order.items)
  1804. .join(Item.keywords)
  1805. )
  1806. .. note:: as seen in the above example, **the order in which each
  1807. call to the join() method occurs is important**. Query would not,
  1808. for example, know how to join correctly if we were to specify
  1809. ``User``, then ``Item``, then ``Order``, in our chain of joins; in
  1810. such a case, depending on the arguments passed, it may raise an
  1811. error that it doesn't know how to join, or it may produce invalid
  1812. SQL in which case the database will raise an error. In correct
  1813. practice, the
  1814. :meth:`_query.Query.join` method is invoked in such a way that lines
  1815. up with how we would want the JOIN clauses in SQL to be
  1816. rendered, and each call should represent a clear link from what
  1817. precedes it.
  1818. **Joins to a Target Entity or Selectable**
  1819. A second form of :meth:`_query.Query.join` allows any mapped entity or
  1820. core selectable construct as a target. In this usage,
  1821. :meth:`_query.Query.join` will attempt to create a JOIN along the
  1822. natural foreign key relationship between two entities::
  1823. q = session.query(User).join(Address)
  1824. In the above calling form, :meth:`_query.Query.join` is called upon to
  1825. create the "on clause" automatically for us. This calling form will
  1826. ultimately raise an error if either there are no foreign keys between
  1827. the two entities, or if there are multiple foreign key linkages between
  1828. the target entity and the entity or entities already present on the
  1829. left side such that creating a join requires more information. Note
  1830. that when indicating a join to a target without any ON clause, ORM
  1831. configured relationships are not taken into account.
  1832. **Joins to a Target with an ON Clause**
  1833. The third calling form allows both the target entity as well
  1834. as the ON clause to be passed explicitly. A example that includes
  1835. a SQL expression as the ON clause is as follows::
  1836. q = session.query(User).join(Address, User.id == Address.user_id)
  1837. The above form may also use a relationship-bound attribute as the
  1838. ON clause as well::
  1839. q = session.query(User).join(Address, User.addresses)
  1840. The above syntax can be useful for the case where we wish
  1841. to join to an alias of a particular target entity. If we wanted
  1842. to join to ``Address`` twice, it could be achieved using two
  1843. aliases set up using the :func:`~sqlalchemy.orm.aliased` function::
  1844. a1 = aliased(Address)
  1845. a2 = aliased(Address)
  1846. q = (
  1847. session.query(User)
  1848. .join(a1, User.addresses)
  1849. .join(a2, User.addresses)
  1850. .filter(a1.email_address == "ed@foo.com")
  1851. .filter(a2.email_address == "ed@bar.com")
  1852. )
  1853. The relationship-bound calling form can also specify a target entity
  1854. using the :meth:`_orm.PropComparator.of_type` method; a query
  1855. equivalent to the one above would be::
  1856. a1 = aliased(Address)
  1857. a2 = aliased(Address)
  1858. q = (
  1859. session.query(User)
  1860. .join(User.addresses.of_type(a1))
  1861. .join(User.addresses.of_type(a2))
  1862. .filter(a1.email_address == "ed@foo.com")
  1863. .filter(a2.email_address == "ed@bar.com")
  1864. )
  1865. **Augmenting Built-in ON Clauses**
  1866. As a substitute for providing a full custom ON condition for an
  1867. existing relationship, the :meth:`_orm.PropComparator.and_` function
  1868. may be applied to a relationship attribute to augment additional
  1869. criteria into the ON clause; the additional criteria will be combined
  1870. with the default criteria using AND::
  1871. q = session.query(User).join(
  1872. User.addresses.and_(Address.email_address != "foo@bar.com")
  1873. )
  1874. .. versionadded:: 1.4
  1875. **Joining to Tables and Subqueries**
  1876. The target of a join may also be any table or SELECT statement,
  1877. which may be related to a target entity or not. Use the
  1878. appropriate ``.subquery()`` method in order to make a subquery
  1879. out of a query::
  1880. subq = (
  1881. session.query(Address)
  1882. .filter(Address.email_address == "ed@foo.com")
  1883. .subquery()
  1884. )
  1885. q = session.query(User).join(subq, User.id == subq.c.user_id)
  1886. Joining to a subquery in terms of a specific relationship and/or
  1887. target entity may be achieved by linking the subquery to the
  1888. entity using :func:`_orm.aliased`::
  1889. subq = (
  1890. session.query(Address)
  1891. .filter(Address.email_address == "ed@foo.com")
  1892. .subquery()
  1893. )
  1894. address_subq = aliased(Address, subq)
  1895. q = session.query(User).join(User.addresses.of_type(address_subq))
  1896. **Controlling what to Join From**
  1897. In cases where the left side of the current state of
  1898. :class:`_query.Query` is not in line with what we want to join from,
  1899. the :meth:`_query.Query.select_from` method may be used::
  1900. q = (
  1901. session.query(Address)
  1902. .select_from(User)
  1903. .join(User.addresses)
  1904. .filter(User.name == "ed")
  1905. )
  1906. Which will produce SQL similar to:
  1907. .. sourcecode:: sql
  1908. SELECT address.* FROM user
  1909. JOIN address ON user.id=address.user_id
  1910. WHERE user.name = :name_1
  1911. .. seealso::
  1912. :meth:`_sql.Select.join` - v2 equivalent method.
  1913. :param \*props: Incoming arguments for :meth:`_query.Query.join`,
  1914. the props collection in modern use should be considered to be a one
  1915. or two argument form, either as a single "target" entity or ORM
  1916. attribute-bound relationship, or as a target entity plus an "on
  1917. clause" which may be a SQL expression or ORM attribute-bound
  1918. relationship.
  1919. :param isouter=False: If True, the join used will be a left outer join,
  1920. just as if the :meth:`_query.Query.outerjoin` method were called.
  1921. :param full=False: render FULL OUTER JOIN; implies ``isouter``.
  1922. """
  1923. join_target = coercions.expect(
  1924. roles.JoinTargetRole,
  1925. target,
  1926. apply_propagate_attrs=self,
  1927. legacy=True,
  1928. )
  1929. if onclause is not None:
  1930. onclause_element = coercions.expect(
  1931. roles.OnClauseRole, onclause, legacy=True
  1932. )
  1933. else:
  1934. onclause_element = None
  1935. self._setup_joins += (
  1936. (
  1937. join_target,
  1938. onclause_element,
  1939. None,
  1940. {
  1941. "isouter": isouter,
  1942. "full": full,
  1943. },
  1944. ),
  1945. )
  1946. self.__dict__.pop("_last_joined_entity", None)
  1947. return self
  1948. def outerjoin(
  1949. self,
  1950. target: _JoinTargetArgument,
  1951. onclause: Optional[_OnClauseArgument] = None,
  1952. *,
  1953. full: bool = False,
  1954. ) -> Self:
  1955. """Create a left outer join against this ``Query`` object's criterion
  1956. and apply generatively, returning the newly resulting ``Query``.
  1957. Usage is the same as the ``join()`` method.
  1958. .. seealso::
  1959. :meth:`_sql.Select.outerjoin` - v2 equivalent method.
  1960. """
  1961. return self.join(target, onclause=onclause, isouter=True, full=full)
  1962. @_generative
  1963. @_assertions(_no_statement_condition)
  1964. def reset_joinpoint(self) -> Self:
  1965. """Return a new :class:`.Query`, where the "join point" has
  1966. been reset back to the base FROM entities of the query.
  1967. This method is usually used in conjunction with the
  1968. ``aliased=True`` feature of the :meth:`~.Query.join`
  1969. method. See the example in :meth:`~.Query.join` for how
  1970. this is used.
  1971. """
  1972. self._last_joined_entity = None
  1973. return self
  1974. @_generative
  1975. @_assertions(_no_clauseelement_condition)
  1976. def select_from(self, *from_obj: _FromClauseArgument) -> Self:
  1977. r"""Set the FROM clause of this :class:`.Query` explicitly.
  1978. :meth:`.Query.select_from` is often used in conjunction with
  1979. :meth:`.Query.join` in order to control which entity is selected
  1980. from on the "left" side of the join.
  1981. The entity or selectable object here effectively replaces the
  1982. "left edge" of any calls to :meth:`~.Query.join`, when no
  1983. joinpoint is otherwise established - usually, the default "join
  1984. point" is the leftmost entity in the :class:`~.Query` object's
  1985. list of entities to be selected.
  1986. A typical example::
  1987. q = (
  1988. session.query(Address)
  1989. .select_from(User)
  1990. .join(User.addresses)
  1991. .filter(User.name == "ed")
  1992. )
  1993. Which produces SQL equivalent to:
  1994. .. sourcecode:: sql
  1995. SELECT address.* FROM user
  1996. JOIN address ON user.id=address.user_id
  1997. WHERE user.name = :name_1
  1998. :param \*from_obj: collection of one or more entities to apply
  1999. to the FROM clause. Entities can be mapped classes,
  2000. :class:`.AliasedClass` objects, :class:`.Mapper` objects
  2001. as well as core :class:`.FromClause` elements like subqueries.
  2002. .. seealso::
  2003. :meth:`~.Query.join`
  2004. :meth:`.Query.select_entity_from`
  2005. :meth:`_sql.Select.select_from` - v2 equivalent method.
  2006. """
  2007. self._set_select_from(from_obj, False)
  2008. return self
  2009. def __getitem__(self, item: Any) -> Any:
  2010. return orm_util._getitem(
  2011. self,
  2012. item,
  2013. )
  2014. @_generative
  2015. @_assertions(_no_statement_condition)
  2016. def slice(
  2017. self,
  2018. start: int,
  2019. stop: int,
  2020. ) -> Self:
  2021. """Computes the "slice" of the :class:`_query.Query` represented by
  2022. the given indices and returns the resulting :class:`_query.Query`.
  2023. The start and stop indices behave like the argument to Python's
  2024. built-in :func:`range` function. This method provides an
  2025. alternative to using ``LIMIT``/``OFFSET`` to get a slice of the
  2026. query.
  2027. For example, ::
  2028. session.query(User).order_by(User.id).slice(1, 3)
  2029. renders as
  2030. .. sourcecode:: sql
  2031. SELECT users.id AS users_id,
  2032. users.name AS users_name
  2033. FROM users ORDER BY users.id
  2034. LIMIT ? OFFSET ?
  2035. (2, 1)
  2036. .. seealso::
  2037. :meth:`_query.Query.limit`
  2038. :meth:`_query.Query.offset`
  2039. :meth:`_sql.Select.slice` - v2 equivalent method.
  2040. """
  2041. self._limit_clause, self._offset_clause = sql_util._make_slice(
  2042. self._limit_clause, self._offset_clause, start, stop
  2043. )
  2044. return self
  2045. @_generative
  2046. @_assertions(_no_statement_condition)
  2047. def limit(self, limit: _LimitOffsetType) -> Self:
  2048. """Apply a ``LIMIT`` to the query and return the newly resulting
  2049. ``Query``.
  2050. .. seealso::
  2051. :meth:`_sql.Select.limit` - v2 equivalent method.
  2052. """
  2053. self._limit_clause = sql_util._offset_or_limit_clause(limit)
  2054. return self
  2055. @_generative
  2056. @_assertions(_no_statement_condition)
  2057. def offset(self, offset: _LimitOffsetType) -> Self:
  2058. """Apply an ``OFFSET`` to the query and return the newly resulting
  2059. ``Query``.
  2060. .. seealso::
  2061. :meth:`_sql.Select.offset` - v2 equivalent method.
  2062. """
  2063. self._offset_clause = sql_util._offset_or_limit_clause(offset)
  2064. return self
  2065. @_generative
  2066. @_assertions(_no_statement_condition)
  2067. def distinct(self, *expr: _ColumnExpressionArgument[Any]) -> Self:
  2068. r"""Apply a ``DISTINCT`` to the query and return the newly resulting
  2069. ``Query``.
  2070. .. note::
  2071. The ORM-level :meth:`.distinct` call includes logic that will
  2072. automatically add columns from the ORDER BY of the query to the
  2073. columns clause of the SELECT statement, to satisfy the common need
  2074. of the database backend that ORDER BY columns be part of the SELECT
  2075. list when DISTINCT is used. These columns *are not* added to the
  2076. list of columns actually fetched by the :class:`_query.Query`,
  2077. however,
  2078. so would not affect results. The columns are passed through when
  2079. using the :attr:`_query.Query.statement` accessor, however.
  2080. .. deprecated:: 2.0 This logic is deprecated and will be removed
  2081. in SQLAlchemy 2.0. See :ref:`migration_20_query_distinct`
  2082. for a description of this use case in 2.0.
  2083. .. seealso::
  2084. :meth:`_sql.Select.distinct` - v2 equivalent method.
  2085. :param \*expr: optional column expressions. When present,
  2086. the PostgreSQL dialect will render a ``DISTINCT ON (<expressions>)``
  2087. construct.
  2088. .. deprecated:: 1.4 Using \*expr in other dialects is deprecated
  2089. and will raise :class:`_exc.CompileError` in a future version.
  2090. """
  2091. if expr:
  2092. self._distinct = True
  2093. self._distinct_on = self._distinct_on + tuple(
  2094. coercions.expect(roles.ByOfRole, e) for e in expr
  2095. )
  2096. else:
  2097. self._distinct = True
  2098. return self
  2099. def all(self) -> List[_T]:
  2100. """Return the results represented by this :class:`_query.Query`
  2101. as a list.
  2102. This results in an execution of the underlying SQL statement.
  2103. .. warning:: The :class:`_query.Query` object,
  2104. when asked to return either
  2105. a sequence or iterator that consists of full ORM-mapped entities,
  2106. will **deduplicate entries based on primary key**. See the FAQ for
  2107. more details.
  2108. .. seealso::
  2109. :ref:`faq_query_deduplicating`
  2110. .. seealso::
  2111. :meth:`_engine.Result.all` - v2 comparable method.
  2112. :meth:`_engine.Result.scalars` - v2 comparable method.
  2113. """
  2114. return self._iter().all() # type: ignore
  2115. @_generative
  2116. @_assertions(_no_clauseelement_condition)
  2117. def from_statement(self, statement: ExecutableReturnsRows) -> Self:
  2118. """Execute the given SELECT statement and return results.
  2119. This method bypasses all internal statement compilation, and the
  2120. statement is executed without modification.
  2121. The statement is typically either a :func:`_expression.text`
  2122. or :func:`_expression.select` construct, and should return the set
  2123. of columns
  2124. appropriate to the entity class represented by this
  2125. :class:`_query.Query`.
  2126. .. seealso::
  2127. :meth:`_sql.Select.from_statement` - v2 comparable method.
  2128. """
  2129. statement = coercions.expect(
  2130. roles.SelectStatementRole, statement, apply_propagate_attrs=self
  2131. )
  2132. self._statement = statement
  2133. return self
  2134. def first(self) -> Optional[_T]:
  2135. """Return the first result of this ``Query`` or
  2136. None if the result doesn't contain any row.
  2137. first() applies a limit of one within the generated SQL, so that
  2138. only one primary entity row is generated on the server side
  2139. (note this may consist of multiple result rows if join-loaded
  2140. collections are present).
  2141. Calling :meth:`_query.Query.first`
  2142. results in an execution of the underlying
  2143. query.
  2144. .. seealso::
  2145. :meth:`_query.Query.one`
  2146. :meth:`_query.Query.one_or_none`
  2147. :meth:`_engine.Result.first` - v2 comparable method.
  2148. :meth:`_engine.Result.scalars` - v2 comparable method.
  2149. """
  2150. # replicates limit(1) behavior
  2151. if self._statement is not None:
  2152. return self._iter().first() # type: ignore
  2153. else:
  2154. return self.limit(1)._iter().first() # type: ignore
  2155. def one_or_none(self) -> Optional[_T]:
  2156. """Return at most one result or raise an exception.
  2157. Returns ``None`` if the query selects
  2158. no rows. Raises ``sqlalchemy.orm.exc.MultipleResultsFound``
  2159. if multiple object identities are returned, or if multiple
  2160. rows are returned for a query that returns only scalar values
  2161. as opposed to full identity-mapped entities.
  2162. Calling :meth:`_query.Query.one_or_none`
  2163. results in an execution of the
  2164. underlying query.
  2165. .. seealso::
  2166. :meth:`_query.Query.first`
  2167. :meth:`_query.Query.one`
  2168. :meth:`_engine.Result.one_or_none` - v2 comparable method.
  2169. :meth:`_engine.Result.scalar_one_or_none` - v2 comparable method.
  2170. """
  2171. return self._iter().one_or_none() # type: ignore
  2172. def one(self) -> _T:
  2173. """Return exactly one result or raise an exception.
  2174. Raises :class:`_exc.NoResultFound` if the query selects no rows.
  2175. Raises :class:`_exc.MultipleResultsFound` if multiple object identities
  2176. are returned, or if multiple rows are returned for a query that returns
  2177. only scalar values as opposed to full identity-mapped entities.
  2178. Calling :meth:`.one` results in an execution of the underlying query.
  2179. .. seealso::
  2180. :meth:`_query.Query.first`
  2181. :meth:`_query.Query.one_or_none`
  2182. :meth:`_engine.Result.one` - v2 comparable method.
  2183. :meth:`_engine.Result.scalar_one` - v2 comparable method.
  2184. """
  2185. return self._iter().one() # type: ignore
  2186. def scalar(self) -> Any:
  2187. """Return the first element of the first result or None
  2188. if no rows present. If multiple rows are returned,
  2189. raises :class:`_exc.MultipleResultsFound`.
  2190. >>> session.query(Item).scalar()
  2191. <Item>
  2192. >>> session.query(Item.id).scalar()
  2193. 1
  2194. >>> session.query(Item.id).filter(Item.id < 0).scalar()
  2195. None
  2196. >>> session.query(Item.id, Item.name).scalar()
  2197. 1
  2198. >>> session.query(func.count(Parent.id)).scalar()
  2199. 20
  2200. This results in an execution of the underlying query.
  2201. .. seealso::
  2202. :meth:`_engine.Result.scalar` - v2 comparable method.
  2203. """
  2204. # TODO: not sure why we can't use result.scalar() here
  2205. try:
  2206. ret = self.one()
  2207. if not isinstance(ret, collections_abc.Sequence):
  2208. return ret
  2209. return ret[0]
  2210. except sa_exc.NoResultFound:
  2211. return None
  2212. def __iter__(self) -> Iterator[_T]:
  2213. result = self._iter()
  2214. try:
  2215. yield from result # type: ignore
  2216. except GeneratorExit:
  2217. # issue #8710 - direct iteration is not re-usable after
  2218. # an iterable block is broken, so close the result
  2219. result._soft_close()
  2220. raise
  2221. def _iter(self) -> Union[ScalarResult[_T], Result[_T]]:
  2222. # new style execution.
  2223. params = self._params
  2224. statement = self._statement_20()
  2225. result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
  2226. statement,
  2227. params,
  2228. execution_options={"_sa_orm_load_options": self.load_options},
  2229. )
  2230. # legacy: automatically set scalars, unique
  2231. if result._attributes.get("is_single_entity", False):
  2232. result = cast("Result[_T]", result).scalars()
  2233. if (
  2234. result._attributes.get("filtered", False)
  2235. and not self.load_options._yield_per
  2236. ):
  2237. result = result.unique()
  2238. return result
  2239. def __str__(self) -> str:
  2240. statement = self._statement_20()
  2241. try:
  2242. bind = (
  2243. self._get_bind_args(statement, self.session.get_bind)
  2244. if self.session
  2245. else None
  2246. )
  2247. except sa_exc.UnboundExecutionError:
  2248. bind = None
  2249. return str(statement.compile(bind))
  2250. def _get_bind_args(self, statement: Any, fn: Any, **kw: Any) -> Any:
  2251. return fn(clause=statement, **kw)
  2252. @property
  2253. def column_descriptions(self) -> List[ORMColumnDescription]:
  2254. """Return metadata about the columns which would be
  2255. returned by this :class:`_query.Query`.
  2256. Format is a list of dictionaries::
  2257. user_alias = aliased(User, name="user2")
  2258. q = sess.query(User, User.id, user_alias)
  2259. # this expression:
  2260. q.column_descriptions
  2261. # would return:
  2262. [
  2263. {
  2264. "name": "User",
  2265. "type": User,
  2266. "aliased": False,
  2267. "expr": User,
  2268. "entity": User,
  2269. },
  2270. {
  2271. "name": "id",
  2272. "type": Integer(),
  2273. "aliased": False,
  2274. "expr": User.id,
  2275. "entity": User,
  2276. },
  2277. {
  2278. "name": "user2",
  2279. "type": User,
  2280. "aliased": True,
  2281. "expr": user_alias,
  2282. "entity": user_alias,
  2283. },
  2284. ]
  2285. .. seealso::
  2286. This API is available using :term:`2.0 style` queries as well,
  2287. documented at:
  2288. * :ref:`queryguide_inspection`
  2289. * :attr:`.Select.column_descriptions`
  2290. """
  2291. return _column_descriptions(self, legacy=True)
  2292. @util.deprecated(
  2293. "2.0",
  2294. "The :meth:`_orm.Query.instances` method is deprecated and will "
  2295. "be removed in a future release. "
  2296. "Use the Select.from_statement() method or aliased() construct in "
  2297. "conjunction with Session.execute() instead.",
  2298. )
  2299. def instances(
  2300. self,
  2301. result_proxy: CursorResult[Any],
  2302. context: Optional[QueryContext] = None,
  2303. ) -> Any:
  2304. """Return an ORM result given a :class:`_engine.CursorResult` and
  2305. :class:`.QueryContext`.
  2306. """
  2307. if context is None:
  2308. util.warn_deprecated(
  2309. "Using the Query.instances() method without a context "
  2310. "is deprecated and will be disallowed in a future release. "
  2311. "Please make use of :meth:`_query.Query.from_statement` "
  2312. "for linking ORM results to arbitrary select constructs.",
  2313. version="1.4",
  2314. )
  2315. compile_state = self._compile_state(for_statement=False)
  2316. context = QueryContext(
  2317. compile_state,
  2318. compile_state.statement,
  2319. compile_state.statement,
  2320. self._params,
  2321. self.session,
  2322. self.load_options,
  2323. )
  2324. result = loading.instances(result_proxy, context)
  2325. # legacy: automatically set scalars, unique
  2326. if result._attributes.get("is_single_entity", False):
  2327. result = result.scalars() # type: ignore
  2328. if result._attributes.get("filtered", False):
  2329. result = result.unique()
  2330. # TODO: isn't this supposed to be a list?
  2331. return result
  2332. @util.became_legacy_20(
  2333. ":meth:`_orm.Query.merge_result`",
  2334. alternative="The method is superseded by the "
  2335. ":func:`_orm.merge_frozen_result` function.",
  2336. enable_warnings=False, # warnings occur via loading.merge_result
  2337. )
  2338. def merge_result(
  2339. self,
  2340. iterator: Union[
  2341. FrozenResult[Any], Iterable[Sequence[Any]], Iterable[object]
  2342. ],
  2343. load: bool = True,
  2344. ) -> Union[FrozenResult[Any], Iterable[Any]]:
  2345. """Merge a result into this :class:`_query.Query` object's Session.
  2346. Given an iterator returned by a :class:`_query.Query`
  2347. of the same structure
  2348. as this one, return an identical iterator of results, with all mapped
  2349. instances merged into the session using :meth:`.Session.merge`. This
  2350. is an optimized method which will merge all mapped instances,
  2351. preserving the structure of the result rows and unmapped columns with
  2352. less method overhead than that of calling :meth:`.Session.merge`
  2353. explicitly for each value.
  2354. The structure of the results is determined based on the column list of
  2355. this :class:`_query.Query` - if these do not correspond,
  2356. unchecked errors
  2357. will occur.
  2358. The 'load' argument is the same as that of :meth:`.Session.merge`.
  2359. For an example of how :meth:`_query.Query.merge_result` is used, see
  2360. the source code for the example :ref:`examples_caching`, where
  2361. :meth:`_query.Query.merge_result` is used to efficiently restore state
  2362. from a cache back into a target :class:`.Session`.
  2363. """
  2364. return loading.merge_result(self, iterator, load)
  2365. def exists(self) -> Exists:
  2366. """A convenience method that turns a query into an EXISTS subquery
  2367. of the form EXISTS (SELECT 1 FROM ... WHERE ...).
  2368. e.g.::
  2369. q = session.query(User).filter(User.name == "fred")
  2370. session.query(q.exists())
  2371. Producing SQL similar to:
  2372. .. sourcecode:: sql
  2373. SELECT EXISTS (
  2374. SELECT 1 FROM users WHERE users.name = :name_1
  2375. ) AS anon_1
  2376. The EXISTS construct is usually used in the WHERE clause::
  2377. session.query(User.id).filter(q.exists()).scalar()
  2378. Note that some databases such as SQL Server don't allow an
  2379. EXISTS expression to be present in the columns clause of a
  2380. SELECT. To select a simple boolean value based on the exists
  2381. as a WHERE, use :func:`.literal`::
  2382. from sqlalchemy import literal
  2383. session.query(literal(True)).filter(q.exists()).scalar()
  2384. .. seealso::
  2385. :meth:`_sql.Select.exists` - v2 comparable method.
  2386. """
  2387. # .add_columns() for the case that we are a query().select_from(X),
  2388. # so that ".statement" can be produced (#2995) but also without
  2389. # omitting the FROM clause from a query(X) (#2818);
  2390. # .with_only_columns() after we have a core select() so that
  2391. # we get just "SELECT 1" without any entities.
  2392. inner = (
  2393. self.enable_eagerloads(False)
  2394. .add_columns(sql.literal_column("1"))
  2395. .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
  2396. ._get_select_statement_only()
  2397. .with_only_columns(1)
  2398. )
  2399. ezero = self._entity_from_pre_ent_zero()
  2400. if ezero is not None:
  2401. inner = inner.select_from(ezero)
  2402. return sql.exists(inner)
  2403. def count(self) -> int:
  2404. r"""Return a count of rows this the SQL formed by this :class:`Query`
  2405. would return.
  2406. This generates the SQL for this Query as follows:
  2407. .. sourcecode:: sql
  2408. SELECT count(1) AS count_1 FROM (
  2409. SELECT <rest of query follows...>
  2410. ) AS anon_1
  2411. The above SQL returns a single row, which is the aggregate value
  2412. of the count function; the :meth:`_query.Query.count`
  2413. method then returns
  2414. that single integer value.
  2415. .. warning::
  2416. It is important to note that the value returned by
  2417. count() is **not the same as the number of ORM objects that this
  2418. Query would return from a method such as the .all() method**.
  2419. The :class:`_query.Query` object,
  2420. when asked to return full entities,
  2421. will **deduplicate entries based on primary key**, meaning if the
  2422. same primary key value would appear in the results more than once,
  2423. only one object of that primary key would be present. This does
  2424. not apply to a query that is against individual columns.
  2425. .. seealso::
  2426. :ref:`faq_query_deduplicating`
  2427. For fine grained control over specific columns to count, to skip the
  2428. usage of a subquery or otherwise control of the FROM clause, or to use
  2429. other aggregate functions, use :attr:`~sqlalchemy.sql.expression.func`
  2430. expressions in conjunction with :meth:`~.Session.query`, i.e.::
  2431. from sqlalchemy import func
  2432. # count User records, without
  2433. # using a subquery.
  2434. session.query(func.count(User.id))
  2435. # return count of user "id" grouped
  2436. # by "name"
  2437. session.query(func.count(User.id)).group_by(User.name)
  2438. from sqlalchemy import distinct
  2439. # count distinct "name" values
  2440. session.query(func.count(distinct(User.name)))
  2441. .. seealso::
  2442. :ref:`migration_20_query_usage`
  2443. """
  2444. col = sql.func.count(sql.literal_column("*"))
  2445. return ( # type: ignore
  2446. self._legacy_from_self(col).enable_eagerloads(False).scalar()
  2447. )
  2448. def delete(
  2449. self,
  2450. synchronize_session: SynchronizeSessionArgument = "auto",
  2451. delete_args: Optional[Dict[Any, Any]] = None,
  2452. ) -> int:
  2453. r"""Perform a DELETE with an arbitrary WHERE clause.
  2454. Deletes rows matched by this query from the database.
  2455. E.g.::
  2456. sess.query(User).filter(User.age == 25).delete(synchronize_session=False)
  2457. sess.query(User).filter(User.age == 25).delete(
  2458. synchronize_session="evaluate"
  2459. )
  2460. .. warning::
  2461. See the section :ref:`orm_expression_update_delete` for important
  2462. caveats and warnings, including limitations when using bulk UPDATE
  2463. and DELETE with mapper inheritance configurations.
  2464. :param synchronize_session: chooses the strategy to update the
  2465. attributes on objects in the session. See the section
  2466. :ref:`orm_expression_update_delete` for a discussion of these
  2467. strategies.
  2468. :param delete_args: Optional dictionary, if present will be passed
  2469. to the underlying :func:`_expression.delete` construct as the ``**kw``
  2470. for the object. May be used to pass dialect-specific arguments such
  2471. as ``mysql_limit``.
  2472. .. versionadded:: 2.0.37
  2473. :return: the count of rows matched as returned by the database's
  2474. "row count" feature.
  2475. .. seealso::
  2476. :ref:`orm_expression_update_delete`
  2477. """ # noqa: E501
  2478. bulk_del = BulkDelete(self, delete_args)
  2479. if self.dispatch.before_compile_delete:
  2480. for fn in self.dispatch.before_compile_delete:
  2481. new_query = fn(bulk_del.query, bulk_del)
  2482. if new_query is not None:
  2483. bulk_del.query = new_query
  2484. self = bulk_del.query
  2485. delete_ = sql.delete(*self._raw_columns) # type: ignore
  2486. if delete_args:
  2487. delete_ = delete_.with_dialect_options(**delete_args)
  2488. delete_._where_criteria = self._where_criteria
  2489. result: CursorResult[Any] = self.session.execute(
  2490. delete_,
  2491. self._params,
  2492. execution_options=self._execution_options.union(
  2493. {"synchronize_session": synchronize_session}
  2494. ),
  2495. )
  2496. bulk_del.result = result # type: ignore
  2497. self.session.dispatch.after_bulk_delete(bulk_del)
  2498. result.close()
  2499. return result.rowcount
  2500. def update(
  2501. self,
  2502. values: Dict[_DMLColumnArgument, Any],
  2503. synchronize_session: SynchronizeSessionArgument = "auto",
  2504. update_args: Optional[Dict[Any, Any]] = None,
  2505. ) -> int:
  2506. r"""Perform an UPDATE with an arbitrary WHERE clause.
  2507. Updates rows matched by this query in the database.
  2508. E.g.::
  2509. sess.query(User).filter(User.age == 25).update(
  2510. {User.age: User.age - 10}, synchronize_session=False
  2511. )
  2512. sess.query(User).filter(User.age == 25).update(
  2513. {"age": User.age - 10}, synchronize_session="evaluate"
  2514. )
  2515. .. warning::
  2516. See the section :ref:`orm_expression_update_delete` for important
  2517. caveats and warnings, including limitations when using arbitrary
  2518. UPDATE and DELETE with mapper inheritance configurations.
  2519. :param values: a dictionary with attributes names, or alternatively
  2520. mapped attributes or SQL expressions, as keys, and literal
  2521. values or sql expressions as values. If :ref:`parameter-ordered
  2522. mode <tutorial_parameter_ordered_updates>` is desired, the values can
  2523. be passed as a list of 2-tuples; this requires that the
  2524. :paramref:`~sqlalchemy.sql.expression.update.preserve_parameter_order`
  2525. flag is passed to the :paramref:`.Query.update.update_args` dictionary
  2526. as well.
  2527. :param synchronize_session: chooses the strategy to update the
  2528. attributes on objects in the session. See the section
  2529. :ref:`orm_expression_update_delete` for a discussion of these
  2530. strategies.
  2531. :param update_args: Optional dictionary, if present will be passed
  2532. to the underlying :func:`_expression.update` construct as the ``**kw``
  2533. for the object. May be used to pass dialect-specific arguments such
  2534. as ``mysql_limit``, as well as other special arguments such as
  2535. :paramref:`~sqlalchemy.sql.expression.update.preserve_parameter_order`.
  2536. :return: the count of rows matched as returned by the database's
  2537. "row count" feature.
  2538. .. seealso::
  2539. :ref:`orm_expression_update_delete`
  2540. """
  2541. update_args = update_args or {}
  2542. bulk_ud = BulkUpdate(self, values, update_args)
  2543. if self.dispatch.before_compile_update:
  2544. for fn in self.dispatch.before_compile_update:
  2545. new_query = fn(bulk_ud.query, bulk_ud)
  2546. if new_query is not None:
  2547. bulk_ud.query = new_query
  2548. self = bulk_ud.query
  2549. upd = sql.update(*self._raw_columns) # type: ignore
  2550. ppo = update_args.pop("preserve_parameter_order", False)
  2551. if ppo:
  2552. upd = upd.ordered_values(*values) # type: ignore
  2553. else:
  2554. upd = upd.values(values)
  2555. if update_args:
  2556. upd = upd.with_dialect_options(**update_args)
  2557. upd._where_criteria = self._where_criteria
  2558. result: CursorResult[Any] = self.session.execute(
  2559. upd,
  2560. self._params,
  2561. execution_options=self._execution_options.union(
  2562. {"synchronize_session": synchronize_session}
  2563. ),
  2564. )
  2565. bulk_ud.result = result # type: ignore
  2566. self.session.dispatch.after_bulk_update(bulk_ud)
  2567. result.close()
  2568. return result.rowcount
  2569. def _compile_state(
  2570. self, for_statement: bool = False, **kw: Any
  2571. ) -> ORMCompileState:
  2572. """Create an out-of-compiler ORMCompileState object.
  2573. The ORMCompileState object is normally created directly as a result
  2574. of the SQLCompiler.process() method being handed a Select()
  2575. or FromStatement() object that uses the "orm" plugin. This method
  2576. provides a means of creating this ORMCompileState object directly
  2577. without using the compiler.
  2578. This method is used only for deprecated cases, which include
  2579. the .from_self() method for a Query that has multiple levels
  2580. of .from_self() in use, as well as the instances() method. It is
  2581. also used within the test suite to generate ORMCompileState objects
  2582. for test purposes.
  2583. """
  2584. stmt = self._statement_20(for_statement=for_statement, **kw)
  2585. assert for_statement == stmt._compile_options._for_statement
  2586. # this chooses between ORMFromStatementCompileState and
  2587. # ORMSelectCompileState. We could also base this on
  2588. # query._statement is not None as we have the ORM Query here
  2589. # however this is the more general path.
  2590. compile_state_cls = cast(
  2591. ORMCompileState,
  2592. ORMCompileState._get_plugin_class_for_plugin(stmt, "orm"),
  2593. )
  2594. return compile_state_cls._create_orm_context(
  2595. stmt, toplevel=True, compiler=None
  2596. )
  2597. def _compile_context(self, for_statement: bool = False) -> QueryContext:
  2598. compile_state = self._compile_state(for_statement=for_statement)
  2599. context = QueryContext(
  2600. compile_state,
  2601. compile_state.statement,
  2602. compile_state.statement,
  2603. self._params,
  2604. self.session,
  2605. self.load_options,
  2606. )
  2607. return context
  2608. class AliasOption(interfaces.LoaderOption):
  2609. inherit_cache = False
  2610. @util.deprecated(
  2611. "1.4",
  2612. "The :class:`.AliasOption` object is not necessary "
  2613. "for entities to be matched up to a query that is established "
  2614. "via :meth:`.Query.from_statement` and now does nothing.",
  2615. )
  2616. def __init__(self, alias: Union[Alias, Subquery]):
  2617. r"""Return a :class:`.MapperOption` that will indicate to the
  2618. :class:`_query.Query`
  2619. that the main table has been aliased.
  2620. """
  2621. def process_compile_state(self, compile_state: ORMCompileState) -> None:
  2622. pass
  2623. class BulkUD:
  2624. """State used for the orm.Query version of update() / delete().
  2625. This object is now specific to Query only.
  2626. """
  2627. def __init__(self, query: Query[Any]):
  2628. self.query = query.enable_eagerloads(False)
  2629. self._validate_query_state()
  2630. self.mapper = self.query._entity_from_pre_ent_zero()
  2631. def _validate_query_state(self) -> None:
  2632. for attr, methname, notset, op in (
  2633. ("_limit_clause", "limit()", None, operator.is_),
  2634. ("_offset_clause", "offset()", None, operator.is_),
  2635. ("_order_by_clauses", "order_by()", (), operator.eq),
  2636. ("_group_by_clauses", "group_by()", (), operator.eq),
  2637. ("_distinct", "distinct()", False, operator.is_),
  2638. (
  2639. "_from_obj",
  2640. "join(), outerjoin(), select_from(), or from_self()",
  2641. (),
  2642. operator.eq,
  2643. ),
  2644. (
  2645. "_setup_joins",
  2646. "join(), outerjoin(), select_from(), or from_self()",
  2647. (),
  2648. operator.eq,
  2649. ),
  2650. ):
  2651. if not op(getattr(self.query, attr), notset):
  2652. raise sa_exc.InvalidRequestError(
  2653. "Can't call Query.update() or Query.delete() "
  2654. "when %s has been called" % (methname,)
  2655. )
  2656. @property
  2657. def session(self) -> Session:
  2658. return self.query.session
  2659. class BulkUpdate(BulkUD):
  2660. """BulkUD which handles UPDATEs."""
  2661. def __init__(
  2662. self,
  2663. query: Query[Any],
  2664. values: Dict[_DMLColumnArgument, Any],
  2665. update_kwargs: Optional[Dict[Any, Any]],
  2666. ):
  2667. super().__init__(query)
  2668. self.values = values
  2669. self.update_kwargs = update_kwargs
  2670. class BulkDelete(BulkUD):
  2671. """BulkUD which handles DELETEs."""
  2672. def __init__(
  2673. self,
  2674. query: Query[Any],
  2675. delete_kwargs: Optional[Dict[Any, Any]],
  2676. ):
  2677. super().__init__(query)
  2678. self.delete_kwargs = delete_kwargs
  2679. class RowReturningQuery(Query[Row[_TP]]):
  2680. if TYPE_CHECKING:
  2681. def tuples(self) -> Query[_TP]: # type: ignore
  2682. ...