query.py 123 KB

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