query.py 155 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187
  1. # orm/query.py
  2. # Copyright (C) 2005-2017 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: http://www.opensource.org/licenses/mit-license.php
  7. """The Query class and support.
  8. Defines the :class:`.Query` class, the central
  9. construct used by the ORM to construct database queries.
  10. The :class:`.Query` class should not be confused with the
  11. :class:`.Select` class, which defines database
  12. SELECT operations at the SQL (non-ORM) level. ``Query`` differs from
  13. ``Select`` in that it returns ORM-mapped objects and interacts with an
  14. ORM session, whereas the ``Select`` construct interacts directly with the
  15. database to return iterable result sets.
  16. """
  17. from itertools import chain
  18. from . import (
  19. attributes, interfaces, object_mapper, persistence,
  20. exc as orm_exc, loading
  21. )
  22. from .base import _entity_descriptor, _is_aliased_class, \
  23. _is_mapped_class, _orm_columns, _generative, InspectionAttr
  24. from .path_registry import PathRegistry
  25. from .util import (
  26. AliasedClass, ORMAdapter, join as orm_join, with_parent, aliased
  27. )
  28. from .. import sql, util, log, exc as sa_exc, inspect, inspection
  29. from ..sql.expression import _interpret_as_from
  30. from ..sql import (
  31. util as sql_util,
  32. expression, visitors
  33. )
  34. from ..sql.base import ColumnCollection
  35. from . import properties
  36. __all__ = ['Query', 'QueryContext', 'aliased']
  37. _path_registry = PathRegistry.root
  38. @inspection._self_inspects
  39. @log.class_logger
  40. class Query(object):
  41. """ORM-level SQL construction object.
  42. :class:`.Query` is the source of all SELECT statements generated by the
  43. ORM, both those formulated by end-user query operations as well as by
  44. high level internal operations such as related collection loading. It
  45. features a generative interface whereby successive calls return a new
  46. :class:`.Query` object, a copy of the former with additional
  47. criteria and options associated with it.
  48. :class:`.Query` objects are normally initially generated using the
  49. :meth:`~.Session.query` method of :class:`.Session`, and in
  50. less common cases by instantiating the :class:`.Query` directly and
  51. associating with a :class:`.Session` using the :meth:`.Query.with_session`
  52. method.
  53. For a full walkthrough of :class:`.Query` usage, see the
  54. :ref:`ormtutorial_toplevel`.
  55. """
  56. _enable_eagerloads = True
  57. _enable_assertions = True
  58. _with_labels = False
  59. _criterion = None
  60. _yield_per = None
  61. _order_by = False
  62. _group_by = False
  63. _having = None
  64. _distinct = False
  65. _prefixes = None
  66. _suffixes = None
  67. _offset = None
  68. _limit = None
  69. _for_update_arg = None
  70. _statement = None
  71. _correlate = frozenset()
  72. _populate_existing = False
  73. _invoke_all_eagers = True
  74. _version_check = False
  75. _autoflush = True
  76. _only_load_props = None
  77. _refresh_state = None
  78. _from_obj = ()
  79. _join_entities = ()
  80. _select_from_entity = None
  81. _mapper_adapter_map = {}
  82. _filter_aliases = None
  83. _from_obj_alias = None
  84. _joinpath = _joinpoint = util.immutabledict()
  85. _execution_options = util.immutabledict()
  86. _params = util.immutabledict()
  87. _attributes = util.immutabledict()
  88. _with_options = ()
  89. _with_hints = ()
  90. _enable_single_crit = True
  91. _orm_only_adapt = True
  92. _orm_only_from_obj_alias = True
  93. _current_path = _path_registry
  94. _has_mapper_entities = False
  95. def __init__(self, entities, session=None):
  96. """Construct a :class:`.Query` directly.
  97. E.g.::
  98. q = Query([User, Address], session=some_session)
  99. The above is equivalent to::
  100. q = some_session.query(User, Address)
  101. :param entities: a sequence of entities and/or SQL expressions.
  102. :param session: a :class:`.Session` with which the :class:`.Query`
  103. will be associated. Optional; a :class:`.Query` can be associated
  104. with a :class:`.Session` generatively via the
  105. :meth:`.Query.with_session` method as well.
  106. .. seealso::
  107. :meth:`.Session.query`
  108. :meth:`.Query.with_session`
  109. """
  110. self.session = session
  111. self._polymorphic_adapters = {}
  112. self._set_entities(entities)
  113. def _set_entities(self, entities, entity_wrapper=None):
  114. if entity_wrapper is None:
  115. entity_wrapper = _QueryEntity
  116. self._entities = []
  117. self._primary_entity = None
  118. self._has_mapper_entities = False
  119. for ent in util.to_list(entities):
  120. entity_wrapper(self, ent)
  121. self._set_entity_selectables(self._entities)
  122. def _set_entity_selectables(self, entities):
  123. self._mapper_adapter_map = d = self._mapper_adapter_map.copy()
  124. for ent in entities:
  125. for entity in ent.entities:
  126. if entity not in d:
  127. ext_info = inspect(entity)
  128. if not ext_info.is_aliased_class and \
  129. ext_info.mapper.with_polymorphic:
  130. if ext_info.mapper.mapped_table not in \
  131. self._polymorphic_adapters:
  132. self._mapper_loads_polymorphically_with(
  133. ext_info.mapper,
  134. sql_util.ColumnAdapter(
  135. ext_info.selectable,
  136. ext_info.mapper._equivalent_columns
  137. )
  138. )
  139. aliased_adapter = None
  140. elif ext_info.is_aliased_class:
  141. aliased_adapter = ext_info._adapter
  142. else:
  143. aliased_adapter = None
  144. d[entity] = (
  145. ext_info,
  146. aliased_adapter
  147. )
  148. ent.setup_entity(*d[entity])
  149. def _mapper_loads_polymorphically_with(self, mapper, adapter):
  150. for m2 in mapper._with_polymorphic_mappers or [mapper]:
  151. self._polymorphic_adapters[m2] = adapter
  152. for m in m2.iterate_to_root():
  153. self._polymorphic_adapters[m.local_table] = adapter
  154. def _set_select_from(self, obj, set_base_alias):
  155. fa = []
  156. select_from_alias = None
  157. for from_obj in obj:
  158. info = inspect(from_obj)
  159. if hasattr(info, 'mapper') and \
  160. (info.is_mapper or info.is_aliased_class):
  161. self._select_from_entity = info
  162. if set_base_alias and not info.is_aliased_class:
  163. raise sa_exc.ArgumentError(
  164. "A selectable (FromClause) instance is "
  165. "expected when the base alias is being set.")
  166. fa.append(info.selectable)
  167. elif not info.is_selectable:
  168. raise sa_exc.ArgumentError(
  169. "argument is not a mapped class, mapper, "
  170. "aliased(), or FromClause instance.")
  171. else:
  172. if isinstance(from_obj, expression.SelectBase):
  173. from_obj = from_obj.alias()
  174. if set_base_alias:
  175. select_from_alias = from_obj
  176. fa.append(from_obj)
  177. self._from_obj = tuple(fa)
  178. if set_base_alias and \
  179. len(self._from_obj) == 1 and \
  180. isinstance(select_from_alias, expression.Alias):
  181. equivs = self.__all_equivs()
  182. self._from_obj_alias = sql_util.ColumnAdapter(
  183. self._from_obj[0], equivs)
  184. elif set_base_alias and \
  185. len(self._from_obj) == 1 and \
  186. hasattr(info, "mapper") and \
  187. info.is_aliased_class:
  188. self._from_obj_alias = info._adapter
  189. def _reset_polymorphic_adapter(self, mapper):
  190. for m2 in mapper._with_polymorphic_mappers:
  191. self._polymorphic_adapters.pop(m2, None)
  192. for m in m2.iterate_to_root():
  193. self._polymorphic_adapters.pop(m.local_table, None)
  194. def _adapt_polymorphic_element(self, element):
  195. if "parententity" in element._annotations:
  196. search = element._annotations['parententity']
  197. alias = self._polymorphic_adapters.get(search, None)
  198. if alias:
  199. return alias.adapt_clause(element)
  200. if isinstance(element, expression.FromClause):
  201. search = element
  202. elif hasattr(element, 'table'):
  203. search = element.table
  204. else:
  205. return None
  206. alias = self._polymorphic_adapters.get(search, None)
  207. if alias:
  208. return alias.adapt_clause(element)
  209. def _adapt_col_list(self, cols):
  210. return [
  211. self._adapt_clause(
  212. expression._literal_as_label_reference(o),
  213. True, True)
  214. for o in cols
  215. ]
  216. @_generative()
  217. def _adapt_all_clauses(self):
  218. self._orm_only_adapt = False
  219. def _adapt_clause(self, clause, as_filter, orm_only):
  220. """Adapt incoming clauses to transformations which
  221. have been applied within this query."""
  222. adapters = []
  223. # do we adapt all expression elements or only those
  224. # tagged as 'ORM' constructs ?
  225. if not self._orm_only_adapt:
  226. orm_only = False
  227. if as_filter and self._filter_aliases:
  228. for fa in self._filter_aliases._visitor_iterator:
  229. adapters.append(
  230. (
  231. orm_only, fa.replace
  232. )
  233. )
  234. if self._from_obj_alias:
  235. # for the "from obj" alias, apply extra rule to the
  236. # 'ORM only' check, if this query were generated from a
  237. # subquery of itself, i.e. _from_selectable(), apply adaption
  238. # to all SQL constructs.
  239. adapters.append(
  240. (
  241. orm_only if self._orm_only_from_obj_alias else False,
  242. self._from_obj_alias.replace
  243. )
  244. )
  245. if self._polymorphic_adapters:
  246. adapters.append(
  247. (
  248. orm_only, self._adapt_polymorphic_element
  249. )
  250. )
  251. if not adapters:
  252. return clause
  253. def replace(elem):
  254. for _orm_only, adapter in adapters:
  255. # if 'orm only', look for ORM annotations
  256. # in the element before adapting.
  257. if not _orm_only or \
  258. '_orm_adapt' in elem._annotations or \
  259. "parententity" in elem._annotations:
  260. e = adapter(elem)
  261. if e is not None:
  262. return e
  263. return visitors.replacement_traverse(
  264. clause,
  265. {},
  266. replace
  267. )
  268. def _query_entity_zero(self):
  269. """Return the first QueryEntity."""
  270. return self._entities[0]
  271. def _mapper_zero(self):
  272. """return the Mapper associated with the first QueryEntity."""
  273. return self._entities[0].mapper
  274. def _entity_zero(self):
  275. """Return the 'entity' (mapper or AliasedClass) associated
  276. with the first QueryEntity, or alternatively the 'select from'
  277. entity if specified."""
  278. return self._select_from_entity \
  279. if self._select_from_entity is not None \
  280. else self._query_entity_zero().entity_zero
  281. @property
  282. def _mapper_entities(self):
  283. for ent in self._entities:
  284. if isinstance(ent, _MapperEntity):
  285. yield ent
  286. def _joinpoint_zero(self):
  287. return self._joinpoint.get(
  288. '_joinpoint_entity',
  289. self._entity_zero()
  290. )
  291. def _bind_mapper(self):
  292. ezero = self._entity_zero()
  293. if ezero is not None:
  294. insp = inspect(ezero)
  295. if not insp.is_clause_element:
  296. return insp.mapper
  297. return None
  298. def _only_full_mapper_zero(self, methname):
  299. if self._entities != [self._primary_entity]:
  300. raise sa_exc.InvalidRequestError(
  301. "%s() can only be used against "
  302. "a single mapped class." % methname)
  303. return self._primary_entity.entity_zero
  304. def _only_entity_zero(self, rationale=None):
  305. if len(self._entities) > 1:
  306. raise sa_exc.InvalidRequestError(
  307. rationale or
  308. "This operation requires a Query "
  309. "against a single mapper."
  310. )
  311. return self._entity_zero()
  312. def __all_equivs(self):
  313. equivs = {}
  314. for ent in self._mapper_entities:
  315. equivs.update(ent.mapper._equivalent_columns)
  316. return equivs
  317. def _get_condition(self):
  318. return self._no_criterion_condition(
  319. "get", order_by=False, distinct=False)
  320. def _get_existing_condition(self):
  321. self._no_criterion_assertion("get", order_by=False, distinct=False)
  322. def _no_criterion_assertion(self, meth, order_by=True, distinct=True):
  323. if not self._enable_assertions:
  324. return
  325. if self._criterion is not None or \
  326. self._statement is not None or self._from_obj or \
  327. self._limit is not None or self._offset is not None or \
  328. self._group_by or (order_by and self._order_by) or \
  329. (distinct and self._distinct):
  330. raise sa_exc.InvalidRequestError(
  331. "Query.%s() being called on a "
  332. "Query with existing criterion. " % meth)
  333. def _no_criterion_condition(self, meth, order_by=True, distinct=True):
  334. self._no_criterion_assertion(meth, order_by, distinct)
  335. self._from_obj = ()
  336. self._statement = self._criterion = None
  337. self._order_by = self._group_by = self._distinct = False
  338. def _no_clauseelement_condition(self, meth):
  339. if not self._enable_assertions:
  340. return
  341. if self._order_by:
  342. raise sa_exc.InvalidRequestError(
  343. "Query.%s() being called on a "
  344. "Query with existing criterion. " % meth)
  345. self._no_criterion_condition(meth)
  346. def _no_statement_condition(self, meth):
  347. if not self._enable_assertions:
  348. return
  349. if self._statement is not None:
  350. raise sa_exc.InvalidRequestError(
  351. ("Query.%s() being called on a Query with an existing full "
  352. "statement - can't apply criterion.") % meth)
  353. def _no_limit_offset(self, meth):
  354. if not self._enable_assertions:
  355. return
  356. if self._limit is not None or self._offset is not None:
  357. raise sa_exc.InvalidRequestError(
  358. "Query.%s() being called on a Query which already has LIMIT "
  359. "or OFFSET applied. To modify the row-limited results of a "
  360. " Query, call from_self() first. "
  361. "Otherwise, call %s() before limit() or offset() "
  362. "are applied."
  363. % (meth, meth)
  364. )
  365. def _get_options(self, populate_existing=None,
  366. version_check=None,
  367. only_load_props=None,
  368. refresh_state=None):
  369. if populate_existing:
  370. self._populate_existing = populate_existing
  371. if version_check:
  372. self._version_check = version_check
  373. if refresh_state:
  374. self._refresh_state = refresh_state
  375. if only_load_props:
  376. self._only_load_props = set(only_load_props)
  377. return self
  378. def _clone(self):
  379. cls = self.__class__
  380. q = cls.__new__(cls)
  381. q.__dict__ = self.__dict__.copy()
  382. return q
  383. @property
  384. def statement(self):
  385. """The full SELECT statement represented by this Query.
  386. The statement by default will not have disambiguating labels
  387. applied to the construct unless with_labels(True) is called
  388. first.
  389. """
  390. stmt = self._compile_context(labels=self._with_labels).\
  391. statement
  392. if self._params:
  393. stmt = stmt.params(self._params)
  394. # TODO: there's no tests covering effects of
  395. # the annotation not being there
  396. return stmt._annotate({'no_replacement_traverse': True})
  397. def subquery(self, name=None, with_labels=False, reduce_columns=False):
  398. """return the full SELECT statement represented by
  399. this :class:`.Query`, embedded within an :class:`.Alias`.
  400. Eager JOIN generation within the query is disabled.
  401. :param name: string name to be assigned as the alias;
  402. this is passed through to :meth:`.FromClause.alias`.
  403. If ``None``, a name will be deterministically generated
  404. at compile time.
  405. :param with_labels: if True, :meth:`.with_labels` will be called
  406. on the :class:`.Query` first to apply table-qualified labels
  407. to all columns.
  408. :param reduce_columns: if True, :meth:`.Select.reduce_columns` will
  409. be called on the resulting :func:`.select` construct,
  410. to remove same-named columns where one also refers to the other
  411. via foreign key or WHERE clause equivalence.
  412. .. versionchanged:: 0.8 the ``with_labels`` and ``reduce_columns``
  413. keyword arguments were added.
  414. """
  415. q = self.enable_eagerloads(False)
  416. if with_labels:
  417. q = q.with_labels()
  418. q = q.statement
  419. if reduce_columns:
  420. q = q.reduce_columns()
  421. return q.alias(name=name)
  422. def cte(self, name=None, recursive=False):
  423. r"""Return the full SELECT statement represented by this
  424. :class:`.Query` represented as a common table expression (CTE).
  425. Parameters and usage are the same as those of the
  426. :meth:`.SelectBase.cte` method; see that method for
  427. further details.
  428. Here is the `PostgreSQL WITH
  429. RECURSIVE example
  430. <http://www.postgresql.org/docs/8.4/static/queries-with.html>`_.
  431. Note that, in this example, the ``included_parts`` cte and the
  432. ``incl_alias`` alias of it are Core selectables, which
  433. means the columns are accessed via the ``.c.`` attribute. The
  434. ``parts_alias`` object is an :func:`.orm.aliased` instance of the
  435. ``Part`` entity, so column-mapped attributes are available
  436. directly::
  437. from sqlalchemy.orm import aliased
  438. class Part(Base):
  439. __tablename__ = 'part'
  440. part = Column(String, primary_key=True)
  441. sub_part = Column(String, primary_key=True)
  442. quantity = Column(Integer)
  443. included_parts = session.query(
  444. Part.sub_part,
  445. Part.part,
  446. Part.quantity).\
  447. filter(Part.part=="our part").\
  448. cte(name="included_parts", recursive=True)
  449. incl_alias = aliased(included_parts, name="pr")
  450. parts_alias = aliased(Part, name="p")
  451. included_parts = included_parts.union_all(
  452. session.query(
  453. parts_alias.sub_part,
  454. parts_alias.part,
  455. parts_alias.quantity).\
  456. filter(parts_alias.part==incl_alias.c.sub_part)
  457. )
  458. q = session.query(
  459. included_parts.c.sub_part,
  460. func.sum(included_parts.c.quantity).
  461. label('total_quantity')
  462. ).\
  463. group_by(included_parts.c.sub_part)
  464. .. seealso::
  465. :meth:`.HasCTE.cte`
  466. """
  467. return self.enable_eagerloads(False).\
  468. statement.cte(name=name, recursive=recursive)
  469. def label(self, name):
  470. """Return the full SELECT statement represented by this
  471. :class:`.Query`, converted
  472. to a scalar subquery with a label of the given name.
  473. Analogous to :meth:`sqlalchemy.sql.expression.SelectBase.label`.
  474. .. versionadded:: 0.6.5
  475. """
  476. return self.enable_eagerloads(False).statement.label(name)
  477. def as_scalar(self):
  478. """Return the full SELECT statement represented by this
  479. :class:`.Query`, converted to a scalar subquery.
  480. Analogous to :meth:`sqlalchemy.sql.expression.SelectBase.as_scalar`.
  481. .. versionadded:: 0.6.5
  482. """
  483. return self.enable_eagerloads(False).statement.as_scalar()
  484. @property
  485. def selectable(self):
  486. """Return the :class:`.Select` object emitted by this :class:`.Query`.
  487. Used for :func:`.inspect` compatibility, this is equivalent to::
  488. query.enable_eagerloads(False).with_labels().statement
  489. """
  490. return self.__clause_element__()
  491. def __clause_element__(self):
  492. return self.enable_eagerloads(False).with_labels().statement
  493. @_generative()
  494. def enable_eagerloads(self, value):
  495. """Control whether or not eager joins and subqueries are
  496. rendered.
  497. When set to False, the returned Query will not render
  498. eager joins regardless of :func:`~sqlalchemy.orm.joinedload`,
  499. :func:`~sqlalchemy.orm.subqueryload` options
  500. or mapper-level ``lazy='joined'``/``lazy='subquery'``
  501. configurations.
  502. This is used primarily when nesting the Query's
  503. statement into a subquery or other
  504. selectable, or when using :meth:`.Query.yield_per`.
  505. """
  506. self._enable_eagerloads = value
  507. def _no_yield_per(self, message):
  508. raise sa_exc.InvalidRequestError(
  509. "The yield_per Query option is currently not "
  510. "compatible with %s eager loading. Please "
  511. "specify lazyload('*') or query.enable_eagerloads(False) in "
  512. "order to "
  513. "proceed with query.yield_per()." % message)
  514. @_generative()
  515. def with_labels(self):
  516. """Apply column labels to the return value of Query.statement.
  517. Indicates that this Query's `statement` accessor should return
  518. a SELECT statement that applies labels to all columns in the
  519. form <tablename>_<columnname>; this is commonly used to
  520. disambiguate columns from multiple tables which have the same
  521. name.
  522. When the `Query` actually issues SQL to load rows, it always
  523. uses column labeling.
  524. .. note:: The :meth:`.Query.with_labels` method *only* applies
  525. the output of :attr:`.Query.statement`, and *not* to any of
  526. the result-row invoking systems of :class:`.Query` itself, e.g.
  527. :meth:`.Query.first`, :meth:`.Query.all`, etc. To execute
  528. a query using :meth:`.Query.with_labels`, invoke the
  529. :attr:`.Query.statement` using :meth:`.Session.execute`::
  530. result = session.execute(query.with_labels().statement)
  531. """
  532. self._with_labels = True
  533. @_generative()
  534. def enable_assertions(self, value):
  535. """Control whether assertions are generated.
  536. When set to False, the returned Query will
  537. not assert its state before certain operations,
  538. including that LIMIT/OFFSET has not been applied
  539. when filter() is called, no criterion exists
  540. when get() is called, and no "from_statement()"
  541. exists when filter()/order_by()/group_by() etc.
  542. is called. This more permissive mode is used by
  543. custom Query subclasses to specify criterion or
  544. other modifiers outside of the usual usage patterns.
  545. Care should be taken to ensure that the usage
  546. pattern is even possible. A statement applied
  547. by from_statement() will override any criterion
  548. set by filter() or order_by(), for example.
  549. """
  550. self._enable_assertions = value
  551. @property
  552. def whereclause(self):
  553. """A readonly attribute which returns the current WHERE criterion for
  554. this Query.
  555. This returned value is a SQL expression construct, or ``None`` if no
  556. criterion has been established.
  557. """
  558. return self._criterion
  559. @_generative()
  560. def _with_current_path(self, path):
  561. """indicate that this query applies to objects loaded
  562. within a certain path.
  563. Used by deferred loaders (see strategies.py) which transfer
  564. query options from an originating query to a newly generated
  565. query intended for the deferred load.
  566. """
  567. self._current_path = path
  568. @_generative(_no_clauseelement_condition)
  569. def with_polymorphic(self,
  570. cls_or_mappers,
  571. selectable=None,
  572. polymorphic_on=None):
  573. """Load columns for inheriting classes.
  574. :meth:`.Query.with_polymorphic` applies transformations
  575. to the "main" mapped class represented by this :class:`.Query`.
  576. The "main" mapped class here means the :class:`.Query`
  577. object's first argument is a full class, i.e.
  578. ``session.query(SomeClass)``. These transformations allow additional
  579. tables to be present in the FROM clause so that columns for a
  580. joined-inheritance subclass are available in the query, both for the
  581. purposes of load-time efficiency as well as the ability to use
  582. these columns at query time.
  583. See the documentation section :ref:`with_polymorphic` for
  584. details on how this method is used.
  585. .. versionchanged:: 0.8
  586. A new and more flexible function
  587. :func:`.orm.with_polymorphic` supersedes
  588. :meth:`.Query.with_polymorphic`, as it can apply the equivalent
  589. functionality to any set of columns or classes in the
  590. :class:`.Query`, not just the "zero mapper". See that
  591. function for a description of arguments.
  592. """
  593. if not self._primary_entity:
  594. raise sa_exc.InvalidRequestError(
  595. "No primary mapper set up for this Query.")
  596. entity = self._entities[0]._clone()
  597. self._entities = [entity] + self._entities[1:]
  598. entity.set_with_polymorphic(self,
  599. cls_or_mappers,
  600. selectable=selectable,
  601. polymorphic_on=polymorphic_on)
  602. @_generative()
  603. def yield_per(self, count):
  604. r"""Yield only ``count`` rows at a time.
  605. The purpose of this method is when fetching very large result sets
  606. (> 10K rows), to batch results in sub-collections and yield them
  607. out partially, so that the Python interpreter doesn't need to declare
  608. very large areas of memory which is both time consuming and leads
  609. to excessive memory use. The performance from fetching hundreds of
  610. thousands of rows can often double when a suitable yield-per setting
  611. (e.g. approximately 1000) is used, even with DBAPIs that buffer
  612. rows (which are most).
  613. The :meth:`.Query.yield_per` method **is not compatible with most
  614. eager loading schemes, including subqueryload and joinedload with
  615. collections**. For this reason, it may be helpful to disable
  616. eager loads, either unconditionally with
  617. :meth:`.Query.enable_eagerloads`::
  618. q = sess.query(Object).yield_per(100).enable_eagerloads(False)
  619. Or more selectively using :func:`.lazyload`; such as with
  620. an asterisk to specify the default loader scheme::
  621. q = sess.query(Object).yield_per(100).\
  622. options(lazyload('*'), joinedload(Object.some_related))
  623. .. warning::
  624. Use this method with caution; if the same instance is
  625. present in more than one batch of rows, end-user changes
  626. to attributes will be overwritten.
  627. In particular, it's usually impossible to use this setting
  628. with eagerly loaded collections (i.e. any lazy='joined' or
  629. 'subquery') since those collections will be cleared for a
  630. new load when encountered in a subsequent result batch.
  631. In the case of 'subquery' loading, the full result for all
  632. rows is fetched which generally defeats the purpose of
  633. :meth:`~sqlalchemy.orm.query.Query.yield_per`.
  634. Also note that while
  635. :meth:`~sqlalchemy.orm.query.Query.yield_per` will set the
  636. ``stream_results`` execution option to True, currently
  637. this is only understood by
  638. :mod:`~sqlalchemy.dialects.postgresql.psycopg2`,
  639. :mod:`~sqlalchemy.dialects.mysql.mysqldb` and
  640. :mod:`~sqlalchemy.dialects.mysql.pymysql` dialects
  641. which will stream results using server side cursors
  642. instead of pre-buffer all rows for this query. Other
  643. DBAPIs **pre-buffer all rows** before making them
  644. available. The memory use of raw database rows is much less
  645. than that of an ORM-mapped object, but should still be taken into
  646. consideration when benchmarking.
  647. .. seealso::
  648. :meth:`.Query.enable_eagerloads`
  649. """
  650. self._yield_per = count
  651. self._execution_options = self._execution_options.union(
  652. {"stream_results": True,
  653. "max_row_buffer": count})
  654. def get(self, ident):
  655. """Return an instance based on the given primary key identifier,
  656. or ``None`` if not found.
  657. E.g.::
  658. my_user = session.query(User).get(5)
  659. some_object = session.query(VersionedFoo).get((5, 10))
  660. :meth:`~.Query.get` is special in that it provides direct
  661. access to the identity map of the owning :class:`.Session`.
  662. If the given primary key identifier is present
  663. in the local identity map, the object is returned
  664. directly from this collection and no SQL is emitted,
  665. unless the object has been marked fully expired.
  666. If not present,
  667. a SELECT is performed in order to locate the object.
  668. :meth:`~.Query.get` also will perform a check if
  669. the object is present in the identity map and
  670. marked as expired - a SELECT
  671. is emitted to refresh the object as well as to
  672. ensure that the row is still present.
  673. If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.
  674. :meth:`~.Query.get` is only used to return a single
  675. mapped instance, not multiple instances or
  676. individual column constructs, and strictly
  677. on a single primary key value. The originating
  678. :class:`.Query` must be constructed in this way,
  679. i.e. against a single mapped entity,
  680. with no additional filtering criterion. Loading
  681. options via :meth:`~.Query.options` may be applied
  682. however, and will be used if the object is not
  683. yet locally present.
  684. A lazy-loading, many-to-one attribute configured
  685. by :func:`.relationship`, using a simple
  686. foreign-key-to-primary-key criterion, will also use an
  687. operation equivalent to :meth:`~.Query.get` in order to retrieve
  688. the target value from the local identity map
  689. before querying the database. See :doc:`/orm/loading_relationships`
  690. for further details on relationship loading.
  691. :param ident: A scalar or tuple value representing
  692. the primary key. For a composite primary key,
  693. the order of identifiers corresponds in most cases
  694. to that of the mapped :class:`.Table` object's
  695. primary key columns. For a :func:`.mapper` that
  696. was given the ``primary key`` argument during
  697. construction, the order of identifiers corresponds
  698. to the elements present in this collection.
  699. :return: The object instance, or ``None``.
  700. """
  701. return self._get_impl(ident, loading.load_on_ident)
  702. def _get_impl(self, ident, fallback_fn):
  703. # convert composite types to individual args
  704. if hasattr(ident, '__composite_values__'):
  705. ident = ident.__composite_values__()
  706. ident = util.to_list(ident)
  707. mapper = self._only_full_mapper_zero("get")
  708. if len(ident) != len(mapper.primary_key):
  709. raise sa_exc.InvalidRequestError(
  710. "Incorrect number of values in identifier to formulate "
  711. "primary key for query.get(); primary key columns are %s" %
  712. ','.join("'%s'" % c for c in mapper.primary_key))
  713. key = mapper.identity_key_from_primary_key(ident)
  714. if not self._populate_existing and \
  715. not mapper.always_refresh and \
  716. self._for_update_arg is None:
  717. instance = loading.get_from_identity(
  718. self.session, key, attributes.PASSIVE_OFF)
  719. if instance is not None:
  720. self._get_existing_condition()
  721. # reject calls for id in identity map but class
  722. # mismatch.
  723. if not issubclass(instance.__class__, mapper.class_):
  724. return None
  725. return instance
  726. return fallback_fn(self, key)
  727. @_generative()
  728. def correlate(self, *args):
  729. """Return a :class:`.Query` construct which will correlate the given
  730. FROM clauses to that of an enclosing :class:`.Query` or
  731. :func:`~.expression.select`.
  732. The method here accepts mapped classes, :func:`.aliased` constructs,
  733. and :func:`.mapper` constructs as arguments, which are resolved into
  734. expression constructs, in addition to appropriate expression
  735. constructs.
  736. The correlation arguments are ultimately passed to
  737. :meth:`.Select.correlate` after coercion to expression constructs.
  738. The correlation arguments take effect in such cases
  739. as when :meth:`.Query.from_self` is used, or when
  740. a subquery as returned by :meth:`.Query.subquery` is
  741. embedded in another :func:`~.expression.select` construct.
  742. """
  743. for s in args:
  744. if s is None:
  745. self._correlate = self._correlate.union([None])
  746. else:
  747. self._correlate = self._correlate.union(
  748. sql_util.surface_selectables(_interpret_as_from(s))
  749. )
  750. @_generative()
  751. def autoflush(self, setting):
  752. """Return a Query with a specific 'autoflush' setting.
  753. Note that a Session with autoflush=False will
  754. not autoflush, even if this flag is set to True at the
  755. Query level. Therefore this flag is usually used only
  756. to disable autoflush for a specific Query.
  757. """
  758. self._autoflush = setting
  759. @_generative()
  760. def populate_existing(self):
  761. """Return a :class:`.Query` that will expire and refresh all instances
  762. as they are loaded, or reused from the current :class:`.Session`.
  763. :meth:`.populate_existing` does not improve behavior when
  764. the ORM is used normally - the :class:`.Session` object's usual
  765. behavior of maintaining a transaction and expiring all attributes
  766. after rollback or commit handles object state automatically.
  767. This method is not intended for general use.
  768. """
  769. self._populate_existing = True
  770. @_generative()
  771. def _with_invoke_all_eagers(self, value):
  772. """Set the 'invoke all eagers' flag which causes joined- and
  773. subquery loaders to traverse into already-loaded related objects
  774. and collections.
  775. Default is that of :attr:`.Query._invoke_all_eagers`.
  776. """
  777. self._invoke_all_eagers = value
  778. def with_parent(self, instance, property=None):
  779. """Add filtering criterion that relates the given instance
  780. to a child object or collection, using its attribute state
  781. as well as an established :func:`.relationship()`
  782. configuration.
  783. The method uses the :func:`.with_parent` function to generate
  784. the clause, the result of which is passed to :meth:`.Query.filter`.
  785. Parameters are the same as :func:`.with_parent`, with the exception
  786. that the given property can be None, in which case a search is
  787. performed against this :class:`.Query` object's target mapper.
  788. """
  789. if property is None:
  790. mapper_zero = self._mapper_zero()
  791. mapper = object_mapper(instance)
  792. for prop in mapper.iterate_properties:
  793. if isinstance(prop, properties.RelationshipProperty) and \
  794. prop.mapper is mapper_zero:
  795. property = prop
  796. break
  797. else:
  798. raise sa_exc.InvalidRequestError(
  799. "Could not locate a property which relates instances "
  800. "of class '%s' to instances of class '%s'" %
  801. (
  802. self._mapper_zero().class_.__name__,
  803. instance.__class__.__name__)
  804. )
  805. return self.filter(with_parent(instance, property))
  806. @_generative()
  807. def add_entity(self, entity, alias=None):
  808. """add a mapped entity to the list of result columns
  809. to be returned."""
  810. if alias is not None:
  811. entity = aliased(entity, alias)
  812. self._entities = list(self._entities)
  813. m = _MapperEntity(self, entity)
  814. self._set_entity_selectables([m])
  815. @_generative()
  816. def with_session(self, session):
  817. """Return a :class:`.Query` that will use the given :class:`.Session`.
  818. While the :class:`.Query` object is normally instantiated using the
  819. :meth:`.Session.query` method, it is legal to build the :class:`.Query`
  820. directly without necessarily using a :class:`.Session`. Such a
  821. :class:`.Query` object, or any :class:`.Query` already associated
  822. with a different :class:`.Session`, can produce a new :class:`.Query`
  823. object associated with a target session using this method::
  824. from sqlalchemy.orm import Query
  825. query = Query([MyClass]).filter(MyClass.id == 5)
  826. result = query.with_session(my_session).one()
  827. """
  828. self.session = session
  829. def from_self(self, *entities):
  830. r"""return a Query that selects from this Query's
  831. SELECT statement.
  832. :meth:`.Query.from_self` essentially turns the SELECT statement
  833. into a SELECT of itself. Given a query such as::
  834. q = session.query(User).filter(User.name.like('e%'))
  835. Given the :meth:`.Query.from_self` version::
  836. q = session.query(User).filter(User.name.like('e%')).from_self()
  837. This query renders as:
  838. .. sourcecode:: sql
  839. SELECT anon_1.user_id AS anon_1_user_id,
  840. anon_1.user_name AS anon_1_user_name
  841. FROM (SELECT "user".id AS user_id, "user".name AS user_name
  842. FROM "user"
  843. WHERE "user".name LIKE :name_1) AS anon_1
  844. There are lots of cases where :meth:`.Query.from_self` may be useful.
  845. A simple one is where above, we may want to apply a row LIMIT to
  846. the set of user objects we query against, and then apply additional
  847. joins against that row-limited set::
  848. q = session.query(User).filter(User.name.like('e%')).\
  849. limit(5).from_self().\
  850. join(User.addresses).filter(Address.email.like('q%'))
  851. The above query joins to the ``Address`` entity but only against the
  852. first five results of the ``User`` query:
  853. .. sourcecode:: sql
  854. SELECT anon_1.user_id AS anon_1_user_id,
  855. anon_1.user_name AS anon_1_user_name
  856. FROM (SELECT "user".id AS user_id, "user".name AS user_name
  857. FROM "user"
  858. WHERE "user".name LIKE :name_1
  859. LIMIT :param_1) AS anon_1
  860. JOIN address ON anon_1.user_id = address.user_id
  861. WHERE address.email LIKE :email_1
  862. **Automatic Aliasing**
  863. Another key behavior of :meth:`.Query.from_self` is that it applies
  864. **automatic aliasing** to the entities inside the subquery, when
  865. they are referenced on the outside. Above, if we continue to
  866. refer to the ``User`` entity without any additional aliasing applied
  867. to it, those references wil be in terms of the subquery::
  868. q = session.query(User).filter(User.name.like('e%')).\
  869. limit(5).from_self().\
  870. join(User.addresses).filter(Address.email.like('q%')).\
  871. order_by(User.name)
  872. The ORDER BY against ``User.name`` is aliased to be in terms of the
  873. inner subquery:
  874. .. sourcecode:: sql
  875. SELECT anon_1.user_id AS anon_1_user_id,
  876. anon_1.user_name AS anon_1_user_name
  877. FROM (SELECT "user".id AS user_id, "user".name AS user_name
  878. FROM "user"
  879. WHERE "user".name LIKE :name_1
  880. LIMIT :param_1) AS anon_1
  881. JOIN address ON anon_1.user_id = address.user_id
  882. WHERE address.email LIKE :email_1 ORDER BY anon_1.user_name
  883. The automatic aliasing feature only works in a **limited** way,
  884. for simple filters and orderings. More ambitious constructions
  885. such as referring to the entity in joins should prefer to use
  886. explicit subquery objects, typically making use of the
  887. :meth:`.Query.subquery` method to produce an explicit subquery object.
  888. Always test the structure of queries by viewing the SQL to ensure
  889. a particular structure does what's expected!
  890. **Changing the Entities**
  891. :meth:`.Query.from_self` also includes the ability to modify what
  892. columns are being queried. In our example, we want ``User.id``
  893. to be queried by the inner query, so that we can join to the
  894. ``Address`` entity on the outside, but we only wanted the outer
  895. query to return the ``Address.email`` column::
  896. q = session.query(User).filter(User.name.like('e%')).\
  897. limit(5).from_self(Address.email).\
  898. join(User.addresses).filter(Address.email.like('q%'))
  899. yielding:
  900. .. sourcecode:: sql
  901. SELECT address.email AS address_email
  902. FROM (SELECT "user".id AS user_id, "user".name AS user_name
  903. FROM "user"
  904. WHERE "user".name LIKE :name_1
  905. LIMIT :param_1) AS anon_1
  906. JOIN address ON anon_1.user_id = address.user_id
  907. WHERE address.email LIKE :email_1
  908. **Looking out for Inner / Outer Columns**
  909. Keep in mind that when referring to columns that originate from
  910. inside the subquery, we need to ensure they are present in the
  911. columns clause of the subquery itself; this is an ordinary aspect of
  912. SQL. For example, if we wanted to load from a joined entity inside
  913. the subquery using :func:`.contains_eager`, we need to add those
  914. columns. Below illustrates a join of ``Address`` to ``User``,
  915. then a subquery, and then we'd like :func:`.contains_eager` to access
  916. the ``User`` columns::
  917. q = session.query(Address).join(Address.user).\
  918. filter(User.name.like('e%'))
  919. q = q.add_entity(User).from_self().\
  920. options(contains_eager(Address.user))
  921. We use :meth:`.Query.add_entity` above **before** we call
  922. :meth:`.Query.from_self` so that the ``User`` columns are present
  923. in the inner subquery, so that they are available to the
  924. :func:`.contains_eager` modifier we are using on the outside,
  925. producing:
  926. .. sourcecode:: sql
  927. SELECT anon_1.address_id AS anon_1_address_id,
  928. anon_1.address_email AS anon_1_address_email,
  929. anon_1.address_user_id AS anon_1_address_user_id,
  930. anon_1.user_id AS anon_1_user_id,
  931. anon_1.user_name AS anon_1_user_name
  932. FROM (
  933. SELECT address.id AS address_id,
  934. address.email AS address_email,
  935. address.user_id AS address_user_id,
  936. "user".id AS user_id,
  937. "user".name AS user_name
  938. FROM address JOIN "user" ON "user".id = address.user_id
  939. WHERE "user".name LIKE :name_1) AS anon_1
  940. If we didn't call ``add_entity(User)``, but still asked
  941. :func:`.contains_eager` to load the ``User`` entity, it would be
  942. forced to add the table on the outside without the correct
  943. join criteria - note the ``anon1, "user"`` phrase at
  944. the end:
  945. .. sourcecode:: sql
  946. -- incorrect query
  947. SELECT anon_1.address_id AS anon_1_address_id,
  948. anon_1.address_email AS anon_1_address_email,
  949. anon_1.address_user_id AS anon_1_address_user_id,
  950. "user".id AS user_id,
  951. "user".name AS user_name
  952. FROM (
  953. SELECT address.id AS address_id,
  954. address.email AS address_email,
  955. address.user_id AS address_user_id
  956. FROM address JOIN "user" ON "user".id = address.user_id
  957. WHERE "user".name LIKE :name_1) AS anon_1, "user"
  958. :param \*entities: optional list of entities which will replace
  959. those being selected.
  960. """
  961. fromclause = self.with_labels().enable_eagerloads(False).\
  962. statement.correlate(None)
  963. q = self._from_selectable(fromclause)
  964. q._enable_single_crit = False
  965. q._select_from_entity = self._entity_zero()
  966. if entities:
  967. q._set_entities(entities)
  968. return q
  969. @_generative()
  970. def _set_enable_single_crit(self, val):
  971. self._enable_single_crit = val
  972. @_generative()
  973. def _from_selectable(self, fromclause):
  974. for attr in (
  975. '_statement', '_criterion',
  976. '_order_by', '_group_by',
  977. '_limit', '_offset',
  978. '_joinpath', '_joinpoint',
  979. '_distinct', '_having',
  980. '_prefixes', '_suffixes'
  981. ):
  982. self.__dict__.pop(attr, None)
  983. self._set_select_from([fromclause], True)
  984. # this enables clause adaptation for non-ORM
  985. # expressions.
  986. self._orm_only_from_obj_alias = False
  987. old_entities = self._entities
  988. self._entities = []
  989. for e in old_entities:
  990. e.adapt_to_selectable(self, self._from_obj[0])
  991. def values(self, *columns):
  992. """Return an iterator yielding result tuples corresponding
  993. to the given list of columns"""
  994. if not columns:
  995. return iter(())
  996. q = self._clone()
  997. q._set_entities(columns, entity_wrapper=_ColumnEntity)
  998. if not q._yield_per:
  999. q._yield_per = 10
  1000. return iter(q)
  1001. _values = values
  1002. def value(self, column):
  1003. """Return a scalar result corresponding to the given
  1004. column expression."""
  1005. try:
  1006. return next(self.values(column))[0]
  1007. except StopIteration:
  1008. return None
  1009. @_generative()
  1010. def with_entities(self, *entities):
  1011. """Return a new :class:`.Query` replacing the SELECT list with the
  1012. given entities.
  1013. e.g.::
  1014. # Users, filtered on some arbitrary criterion
  1015. # and then ordered by related email address
  1016. q = session.query(User).\
  1017. join(User.address).\
  1018. filter(User.name.like('%ed%')).\
  1019. order_by(Address.email)
  1020. # given *only* User.id==5, Address.email, and 'q', what
  1021. # would the *next* User in the result be ?
  1022. subq = q.with_entities(Address.email).\
  1023. order_by(None).\
  1024. filter(User.id==5).\
  1025. subquery()
  1026. q = q.join((subq, subq.c.email < Address.email)).\
  1027. limit(1)
  1028. .. versionadded:: 0.6.5
  1029. """
  1030. self._set_entities(entities)
  1031. @_generative()
  1032. def add_columns(self, *column):
  1033. """Add one or more column expressions to the list
  1034. of result columns to be returned."""
  1035. self._entities = list(self._entities)
  1036. l = len(self._entities)
  1037. for c in column:
  1038. _ColumnEntity(self, c)
  1039. # _ColumnEntity may add many entities if the
  1040. # given arg is a FROM clause
  1041. self._set_entity_selectables(self._entities[l:])
  1042. @util.pending_deprecation("0.7",
  1043. ":meth:`.add_column` is superseded "
  1044. "by :meth:`.add_columns`",
  1045. False)
  1046. def add_column(self, column):
  1047. """Add a column expression to the list of result columns to be
  1048. returned.
  1049. Pending deprecation: :meth:`.add_column` will be superseded by
  1050. :meth:`.add_columns`.
  1051. """
  1052. return self.add_columns(column)
  1053. def options(self, *args):
  1054. """Return a new Query object, applying the given list of
  1055. mapper options.
  1056. Most supplied options regard changing how column- and
  1057. relationship-mapped attributes are loaded. See the sections
  1058. :ref:`deferred` and :doc:`/orm/loading_relationships` for reference
  1059. documentation.
  1060. """
  1061. return self._options(False, *args)
  1062. def _conditional_options(self, *args):
  1063. return self._options(True, *args)
  1064. @_generative()
  1065. def _options(self, conditional, *args):
  1066. # most MapperOptions write to the '_attributes' dictionary,
  1067. # so copy that as well
  1068. self._attributes = self._attributes.copy()
  1069. opts = tuple(util.flatten_iterator(args))
  1070. self._with_options = self._with_options + opts
  1071. if conditional:
  1072. for opt in opts:
  1073. opt.process_query_conditionally(self)
  1074. else:
  1075. for opt in opts:
  1076. opt.process_query(self)
  1077. def with_transformation(self, fn):
  1078. """Return a new :class:`.Query` object transformed by
  1079. the given function.
  1080. E.g.::
  1081. def filter_something(criterion):
  1082. def transform(q):
  1083. return q.filter(criterion)
  1084. return transform
  1085. q = q.with_transformation(filter_something(x==5))
  1086. This allows ad-hoc recipes to be created for :class:`.Query`
  1087. objects. See the example at :ref:`hybrid_transformers`.
  1088. .. versionadded:: 0.7.4
  1089. """
  1090. return fn(self)
  1091. @_generative()
  1092. def with_hint(self, selectable, text, dialect_name='*'):
  1093. """Add an indexing or other executional context
  1094. hint for the given entity or selectable to
  1095. this :class:`.Query`.
  1096. Functionality is passed straight through to
  1097. :meth:`~sqlalchemy.sql.expression.Select.with_hint`,
  1098. with the addition that ``selectable`` can be a
  1099. :class:`.Table`, :class:`.Alias`, or ORM entity / mapped class
  1100. /etc.
  1101. .. seealso::
  1102. :meth:`.Query.with_statement_hint`
  1103. """
  1104. if selectable is not None:
  1105. selectable = inspect(selectable).selectable
  1106. self._with_hints += ((selectable, text, dialect_name),)
  1107. def with_statement_hint(self, text, dialect_name='*'):
  1108. """add a statement hint to this :class:`.Select`.
  1109. This method is similar to :meth:`.Select.with_hint` except that
  1110. it does not require an individual table, and instead applies to the
  1111. statement as a whole.
  1112. This feature calls down into :meth:`.Select.with_statement_hint`.
  1113. .. versionadded:: 1.0.0
  1114. .. seealso::
  1115. :meth:`.Query.with_hint`
  1116. """
  1117. return self.with_hint(None, text, dialect_name)
  1118. @_generative()
  1119. def execution_options(self, **kwargs):
  1120. """ Set non-SQL options which take effect during execution.
  1121. The options are the same as those accepted by
  1122. :meth:`.Connection.execution_options`.
  1123. Note that the ``stream_results`` execution option is enabled
  1124. automatically if the :meth:`~sqlalchemy.orm.query.Query.yield_per()`
  1125. method is used.
  1126. """
  1127. self._execution_options = self._execution_options.union(kwargs)
  1128. @_generative()
  1129. def with_lockmode(self, mode):
  1130. """Return a new :class:`.Query` object with the specified "locking mode",
  1131. which essentially refers to the ``FOR UPDATE`` clause.
  1132. .. deprecated:: 0.9.0 superseded by :meth:`.Query.with_for_update`.
  1133. :param mode: a string representing the desired locking mode.
  1134. Valid values are:
  1135. * ``None`` - translates to no lockmode
  1136. * ``'update'`` - translates to ``FOR UPDATE``
  1137. (standard SQL, supported by most dialects)
  1138. * ``'update_nowait'`` - translates to ``FOR UPDATE NOWAIT``
  1139. (supported by Oracle, PostgreSQL 8.1 upwards)
  1140. * ``'read'`` - translates to ``LOCK IN SHARE MODE`` (for MySQL),
  1141. and ``FOR SHARE`` (for PostgreSQL)
  1142. .. seealso::
  1143. :meth:`.Query.with_for_update` - improved API for
  1144. specifying the ``FOR UPDATE`` clause.
  1145. """
  1146. self._for_update_arg = LockmodeArg.parse_legacy_query(mode)
  1147. @_generative()
  1148. def with_for_update(self, read=False, nowait=False, of=None,
  1149. skip_locked=False, key_share=False):
  1150. """return a new :class:`.Query` with the specified options for the
  1151. ``FOR UPDATE`` clause.
  1152. The behavior of this method is identical to that of
  1153. :meth:`.SelectBase.with_for_update`. When called with no arguments,
  1154. the resulting ``SELECT`` statement will have a ``FOR UPDATE`` clause
  1155. appended. When additional arguments are specified, backend-specific
  1156. options such as ``FOR UPDATE NOWAIT`` or ``LOCK IN SHARE MODE``
  1157. can take effect.
  1158. E.g.::
  1159. q = sess.query(User).with_for_update(nowait=True, of=User)
  1160. The above query on a PostgreSQL backend will render like::
  1161. SELECT users.id AS users_id FROM users FOR UPDATE OF users NOWAIT
  1162. .. versionadded:: 0.9.0 :meth:`.Query.with_for_update` supersedes
  1163. the :meth:`.Query.with_lockmode` method.
  1164. .. seealso::
  1165. :meth:`.GenerativeSelect.with_for_update` - Core level method with
  1166. full argument and behavioral description.
  1167. """
  1168. self._for_update_arg = LockmodeArg(read=read, nowait=nowait, of=of,
  1169. skip_locked=skip_locked,
  1170. key_share=key_share)
  1171. @_generative()
  1172. def params(self, *args, **kwargs):
  1173. r"""add values for bind parameters which may have been
  1174. specified in filter().
  1175. parameters may be specified using \**kwargs, or optionally a single
  1176. dictionary as the first positional argument. The reason for both is
  1177. that \**kwargs is convenient, however some parameter dictionaries
  1178. contain unicode keys in which case \**kwargs cannot be used.
  1179. """
  1180. if len(args) == 1:
  1181. kwargs.update(args[0])
  1182. elif len(args) > 0:
  1183. raise sa_exc.ArgumentError(
  1184. "params() takes zero or one positional argument, "
  1185. "which is a dictionary.")
  1186. self._params = self._params.copy()
  1187. self._params.update(kwargs)
  1188. @_generative(_no_statement_condition, _no_limit_offset)
  1189. def filter(self, *criterion):
  1190. r"""apply the given filtering criterion to a copy
  1191. of this :class:`.Query`, using SQL expressions.
  1192. e.g.::
  1193. session.query(MyClass).filter(MyClass.name == 'some name')
  1194. Multiple criteria may be specified as comma separated; the effect
  1195. is that they will be joined together using the :func:`.and_`
  1196. function::
  1197. session.query(MyClass).\
  1198. filter(MyClass.name == 'some name', MyClass.id > 5)
  1199. The criterion is any SQL expression object applicable to the
  1200. WHERE clause of a select. String expressions are coerced
  1201. into SQL expression constructs via the :func:`.text` construct.
  1202. .. seealso::
  1203. :meth:`.Query.filter_by` - filter on keyword expressions.
  1204. """
  1205. for criterion in list(criterion):
  1206. criterion = expression._expression_literal_as_text(criterion)
  1207. criterion = self._adapt_clause(criterion, True, True)
  1208. if self._criterion is not None:
  1209. self._criterion = self._criterion & criterion
  1210. else:
  1211. self._criterion = criterion
  1212. def filter_by(self, **kwargs):
  1213. r"""apply the given filtering criterion to a copy
  1214. of this :class:`.Query`, using keyword expressions.
  1215. e.g.::
  1216. session.query(MyClass).filter_by(name = 'some name')
  1217. Multiple criteria may be specified as comma separated; the effect
  1218. is that they will be joined together using the :func:`.and_`
  1219. function::
  1220. session.query(MyClass).\
  1221. filter_by(name = 'some name', id = 5)
  1222. The keyword expressions are extracted from the primary
  1223. entity of the query, or the last entity that was the
  1224. target of a call to :meth:`.Query.join`.
  1225. .. seealso::
  1226. :meth:`.Query.filter` - filter on SQL expressions.
  1227. """
  1228. clauses = [_entity_descriptor(self._joinpoint_zero(), key) == value
  1229. for key, value in kwargs.items()]
  1230. return self.filter(sql.and_(*clauses))
  1231. @_generative(_no_statement_condition, _no_limit_offset)
  1232. def order_by(self, *criterion):
  1233. """apply one or more ORDER BY criterion to the query and return
  1234. the newly resulting ``Query``
  1235. All existing ORDER BY settings can be suppressed by
  1236. passing ``None`` - this will suppress any ORDER BY configured
  1237. on mappers as well.
  1238. Alternatively, passing False will reset ORDER BY and additionally
  1239. re-allow default mapper.order_by to take place. Note mapper.order_by
  1240. is deprecated.
  1241. """
  1242. if len(criterion) == 1:
  1243. if criterion[0] is False:
  1244. if '_order_by' in self.__dict__:
  1245. self._order_by = False
  1246. return
  1247. if criterion[0] is None:
  1248. self._order_by = None
  1249. return
  1250. criterion = self._adapt_col_list(criterion)
  1251. if self._order_by is False or self._order_by is None:
  1252. self._order_by = criterion
  1253. else:
  1254. self._order_by = self._order_by + criterion
  1255. @_generative(_no_statement_condition, _no_limit_offset)
  1256. def group_by(self, *criterion):
  1257. """apply one or more GROUP BY criterion to the query and return
  1258. the newly resulting :class:`.Query`
  1259. All existing GROUP BY settings can be suppressed by
  1260. passing ``None`` - this will suppress any GROUP BY configured
  1261. on mappers as well.
  1262. .. versionadded:: 1.1 GROUP BY can be cancelled by passing None,
  1263. in the same way as ORDER BY.
  1264. """
  1265. if len(criterion) == 1:
  1266. if criterion[0] is None:
  1267. self._group_by = False
  1268. return
  1269. criterion = list(chain(*[_orm_columns(c) for c in criterion]))
  1270. criterion = self._adapt_col_list(criterion)
  1271. if self._group_by is False:
  1272. self._group_by = criterion
  1273. else:
  1274. self._group_by = self._group_by + criterion
  1275. @_generative(_no_statement_condition, _no_limit_offset)
  1276. def having(self, criterion):
  1277. r"""apply a HAVING criterion to the query and return the
  1278. newly resulting :class:`.Query`.
  1279. :meth:`~.Query.having` is used in conjunction with
  1280. :meth:`~.Query.group_by`.
  1281. HAVING criterion makes it possible to use filters on aggregate
  1282. functions like COUNT, SUM, AVG, MAX, and MIN, eg.::
  1283. q = session.query(User.id).\
  1284. join(User.addresses).\
  1285. group_by(User.id).\
  1286. having(func.count(Address.id) > 2)
  1287. """
  1288. criterion = expression._expression_literal_as_text(criterion)
  1289. if criterion is not None and \
  1290. not isinstance(criterion, sql.ClauseElement):
  1291. raise sa_exc.ArgumentError(
  1292. "having() argument must be of type "
  1293. "sqlalchemy.sql.ClauseElement or string")
  1294. criterion = self._adapt_clause(criterion, True, True)
  1295. if self._having is not None:
  1296. self._having = self._having & criterion
  1297. else:
  1298. self._having = criterion
  1299. def _set_op(self, expr_fn, *q):
  1300. return self._from_selectable(
  1301. expr_fn(*([self] + list(q)))
  1302. )._set_enable_single_crit(False)
  1303. def union(self, *q):
  1304. """Produce a UNION of this Query against one or more queries.
  1305. e.g.::
  1306. q1 = sess.query(SomeClass).filter(SomeClass.foo=='bar')
  1307. q2 = sess.query(SomeClass).filter(SomeClass.bar=='foo')
  1308. q3 = q1.union(q2)
  1309. The method accepts multiple Query objects so as to control
  1310. the level of nesting. A series of ``union()`` calls such as::
  1311. x.union(y).union(z).all()
  1312. will nest on each ``union()``, and produces::
  1313. SELECT * FROM (SELECT * FROM (SELECT * FROM X UNION
  1314. SELECT * FROM y) UNION SELECT * FROM Z)
  1315. Whereas::
  1316. x.union(y, z).all()
  1317. produces::
  1318. SELECT * FROM (SELECT * FROM X UNION SELECT * FROM y UNION
  1319. SELECT * FROM Z)
  1320. Note that many database backends do not allow ORDER BY to
  1321. be rendered on a query called within UNION, EXCEPT, etc.
  1322. To disable all ORDER BY clauses including those configured
  1323. on mappers, issue ``query.order_by(None)`` - the resulting
  1324. :class:`.Query` object will not render ORDER BY within
  1325. its SELECT statement.
  1326. """
  1327. return self._set_op(expression.union, *q)
  1328. def union_all(self, *q):
  1329. """Produce a UNION ALL of this Query against one or more queries.
  1330. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1331. that method for usage examples.
  1332. """
  1333. return self._set_op(expression.union_all, *q)
  1334. def intersect(self, *q):
  1335. """Produce an INTERSECT of this Query against one or more queries.
  1336. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1337. that method for usage examples.
  1338. """
  1339. return self._set_op(expression.intersect, *q)
  1340. def intersect_all(self, *q):
  1341. """Produce an INTERSECT ALL of this Query against one or more queries.
  1342. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1343. that method for usage examples.
  1344. """
  1345. return self._set_op(expression.intersect_all, *q)
  1346. def except_(self, *q):
  1347. """Produce an EXCEPT of this Query against one or more queries.
  1348. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1349. that method for usage examples.
  1350. """
  1351. return self._set_op(expression.except_, *q)
  1352. def except_all(self, *q):
  1353. """Produce an EXCEPT ALL of this Query against one or more queries.
  1354. Works the same way as :meth:`~sqlalchemy.orm.query.Query.union`. See
  1355. that method for usage examples.
  1356. """
  1357. return self._set_op(expression.except_all, *q)
  1358. def join(self, *props, **kwargs):
  1359. r"""Create a SQL JOIN against this :class:`.Query` object's criterion
  1360. and apply generatively, returning the newly resulting :class:`.Query`.
  1361. **Simple Relationship Joins**
  1362. Consider a mapping between two classes ``User`` and ``Address``,
  1363. with a relationship ``User.addresses`` representing a collection
  1364. of ``Address`` objects associated with each ``User``. The most
  1365. common usage of :meth:`~.Query.join` is to create a JOIN along this
  1366. relationship, using the ``User.addresses`` attribute as an indicator
  1367. for how this should occur::
  1368. q = session.query(User).join(User.addresses)
  1369. Where above, the call to :meth:`~.Query.join` along ``User.addresses``
  1370. will result in SQL equivalent to::
  1371. SELECT user.* FROM user JOIN address ON user.id = address.user_id
  1372. In the above example we refer to ``User.addresses`` as passed to
  1373. :meth:`~.Query.join` as the *on clause*, that is, it indicates
  1374. how the "ON" portion of the JOIN should be constructed. For a
  1375. single-entity query such as the one above (i.e. we start by selecting
  1376. only from ``User`` and nothing else), the relationship can also be
  1377. specified by its string name::
  1378. q = session.query(User).join("addresses")
  1379. :meth:`~.Query.join` can also accommodate multiple
  1380. "on clause" arguments to produce a chain of joins, such as below
  1381. where a join across four related entities is constructed::
  1382. q = session.query(User).join("orders", "items", "keywords")
  1383. The above would be shorthand for three separate calls to
  1384. :meth:`~.Query.join`, each using an explicit attribute to indicate
  1385. the source entity::
  1386. q = session.query(User).\
  1387. join(User.orders).\
  1388. join(Order.items).\
  1389. join(Item.keywords)
  1390. **Joins to a Target Entity or Selectable**
  1391. A second form of :meth:`~.Query.join` allows any mapped entity
  1392. or core selectable construct as a target. In this usage,
  1393. :meth:`~.Query.join` will attempt
  1394. to create a JOIN along the natural foreign key relationship between
  1395. two entities::
  1396. q = session.query(User).join(Address)
  1397. The above calling form of :meth:`~.Query.join` will raise an error if
  1398. either there are no foreign keys between the two entities, or if
  1399. there are multiple foreign key linkages between them. In the
  1400. above calling form, :meth:`~.Query.join` is called upon to
  1401. create the "on clause" automatically for us. The target can
  1402. be any mapped entity or selectable, such as a :class:`.Table`::
  1403. q = session.query(User).join(addresses_table)
  1404. **Joins to a Target with an ON Clause**
  1405. The third calling form allows both the target entity as well
  1406. as the ON clause to be passed explicitly. Suppose for
  1407. example we wanted to join to ``Address`` twice, using
  1408. an alias the second time. We use :func:`~sqlalchemy.orm.aliased`
  1409. to create a distinct alias of ``Address``, and join
  1410. to it using the ``target, onclause`` form, so that the
  1411. alias can be specified explicitly as the target along with
  1412. the relationship to instruct how the ON clause should proceed::
  1413. a_alias = aliased(Address)
  1414. q = session.query(User).\
  1415. join(User.addresses).\
  1416. join(a_alias, User.addresses).\
  1417. filter(Address.email_address=='ed@foo.com').\
  1418. filter(a_alias.email_address=='ed@bar.com')
  1419. Where above, the generated SQL would be similar to::
  1420. SELECT user.* FROM user
  1421. JOIN address ON user.id = address.user_id
  1422. JOIN address AS address_1 ON user.id=address_1.user_id
  1423. WHERE address.email_address = :email_address_1
  1424. AND address_1.email_address = :email_address_2
  1425. The two-argument calling form of :meth:`~.Query.join`
  1426. also allows us to construct arbitrary joins with SQL-oriented
  1427. "on clause" expressions, not relying upon configured relationships
  1428. at all. Any SQL expression can be passed as the ON clause
  1429. when using the two-argument form, which should refer to the target
  1430. entity in some way as well as an applicable source entity::
  1431. q = session.query(User).join(Address, User.id==Address.user_id)
  1432. .. versionchanged:: 0.7
  1433. In SQLAlchemy 0.6 and earlier, the two argument form of
  1434. :meth:`~.Query.join` requires the usage of a tuple:
  1435. ``query(User).join((Address, User.id==Address.user_id))``\ .
  1436. This calling form is accepted in 0.7 and further, though
  1437. is not necessary unless multiple join conditions are passed to
  1438. a single :meth:`~.Query.join` call, which itself is also not
  1439. generally necessary as it is now equivalent to multiple
  1440. calls (this wasn't always the case).
  1441. **Advanced Join Targeting and Adaption**
  1442. There is a lot of flexibility in what the "target" can be when using
  1443. :meth:`~.Query.join`. As noted previously, it also accepts
  1444. :class:`.Table` constructs and other selectables such as
  1445. :func:`.alias` and :func:`.select` constructs, with either the one
  1446. or two-argument forms::
  1447. addresses_q = select([Address.user_id]).\
  1448. where(Address.email_address.endswith("@bar.com")).\
  1449. alias()
  1450. q = session.query(User).\
  1451. join(addresses_q, addresses_q.c.user_id==User.id)
  1452. :meth:`~.Query.join` also features the ability to *adapt* a
  1453. :meth:`~sqlalchemy.orm.relationship` -driven ON clause to the target
  1454. selectable. Below we construct a JOIN from ``User`` to a subquery
  1455. against ``Address``, allowing the relationship denoted by
  1456. ``User.addresses`` to *adapt* itself to the altered target::
  1457. address_subq = session.query(Address).\
  1458. filter(Address.email_address == 'ed@foo.com').\
  1459. subquery()
  1460. q = session.query(User).join(address_subq, User.addresses)
  1461. Producing SQL similar to::
  1462. SELECT user.* FROM user
  1463. JOIN (
  1464. SELECT address.id AS id,
  1465. address.user_id AS user_id,
  1466. address.email_address AS email_address
  1467. FROM address
  1468. WHERE address.email_address = :email_address_1
  1469. ) AS anon_1 ON user.id = anon_1.user_id
  1470. The above form allows one to fall back onto an explicit ON
  1471. clause at any time::
  1472. q = session.query(User).\
  1473. join(address_subq, User.id==address_subq.c.user_id)
  1474. **Controlling what to Join From**
  1475. While :meth:`~.Query.join` exclusively deals with the "right"
  1476. side of the JOIN, we can also control the "left" side, in those
  1477. cases where it's needed, using :meth:`~.Query.select_from`.
  1478. Below we construct a query against ``Address`` but can still
  1479. make usage of ``User.addresses`` as our ON clause by instructing
  1480. the :class:`.Query` to select first from the ``User``
  1481. entity::
  1482. q = session.query(Address).select_from(User).\
  1483. join(User.addresses).\
  1484. filter(User.name == 'ed')
  1485. Which will produce SQL similar to::
  1486. SELECT address.* FROM user
  1487. JOIN address ON user.id=address.user_id
  1488. WHERE user.name = :name_1
  1489. **Constructing Aliases Anonymously**
  1490. :meth:`~.Query.join` can construct anonymous aliases
  1491. using the ``aliased=True`` flag. This feature is useful
  1492. when a query is being joined algorithmically, such as
  1493. when querying self-referentially to an arbitrary depth::
  1494. q = session.query(Node).\
  1495. join("children", "children", aliased=True)
  1496. When ``aliased=True`` is used, the actual "alias" construct
  1497. is not explicitly available. To work with it, methods such as
  1498. :meth:`.Query.filter` will adapt the incoming entity to
  1499. the last join point::
  1500. q = session.query(Node).\
  1501. join("children", "children", aliased=True).\
  1502. filter(Node.name == 'grandchild 1')
  1503. When using automatic aliasing, the ``from_joinpoint=True``
  1504. argument can allow a multi-node join to be broken into
  1505. multiple calls to :meth:`~.Query.join`, so that
  1506. each path along the way can be further filtered::
  1507. q = session.query(Node).\
  1508. join("children", aliased=True).\
  1509. filter(Node.name='child 1').\
  1510. join("children", aliased=True, from_joinpoint=True).\
  1511. filter(Node.name == 'grandchild 1')
  1512. The filtering aliases above can then be reset back to the
  1513. original ``Node`` entity using :meth:`~.Query.reset_joinpoint`::
  1514. q = session.query(Node).\
  1515. join("children", "children", aliased=True).\
  1516. filter(Node.name == 'grandchild 1').\
  1517. reset_joinpoint().\
  1518. filter(Node.name == 'parent 1)
  1519. For an example of ``aliased=True``, see the distribution
  1520. example :ref:`examples_xmlpersistence` which illustrates
  1521. an XPath-like query system using algorithmic joins.
  1522. :param \*props: A collection of one or more join conditions,
  1523. each consisting of a relationship-bound attribute or string
  1524. relationship name representing an "on clause", or a single
  1525. target entity, or a tuple in the form of ``(target, onclause)``.
  1526. A special two-argument calling form of the form ``target, onclause``
  1527. is also accepted.
  1528. :param aliased=False: If True, indicate that the JOIN target should be
  1529. anonymously aliased. Subsequent calls to :meth:`~.Query.filter`
  1530. and similar will adapt the incoming criterion to the target
  1531. alias, until :meth:`~.Query.reset_joinpoint` is called.
  1532. :param isouter=False: If True, the join used will be a left outer join,
  1533. just as if the :meth:`.Query.outerjoin` method were called. This
  1534. flag is here to maintain consistency with the same flag as accepted
  1535. by :meth:`.FromClause.join` and other Core constructs.
  1536. .. versionadded:: 1.0.0
  1537. :param full=False: render FULL OUTER JOIN; implies ``isouter``.
  1538. .. versionadded:: 1.1
  1539. :param from_joinpoint=False: When using ``aliased=True``, a setting
  1540. of True here will cause the join to be from the most recent
  1541. joined target, rather than starting back from the original
  1542. FROM clauses of the query.
  1543. .. seealso::
  1544. :ref:`ormtutorial_joins` in the ORM tutorial.
  1545. :ref:`inheritance_toplevel` for details on how
  1546. :meth:`~.Query.join` is used for inheritance relationships.
  1547. :func:`.orm.join` - a standalone ORM-level join function,
  1548. used internally by :meth:`.Query.join`, which in previous
  1549. SQLAlchemy versions was the primary ORM-level joining interface.
  1550. """
  1551. aliased, from_joinpoint, isouter, full = kwargs.pop('aliased', False),\
  1552. kwargs.pop('from_joinpoint', False),\
  1553. kwargs.pop('isouter', False),\
  1554. kwargs.pop('full', False)
  1555. if kwargs:
  1556. raise TypeError("unknown arguments: %s" %
  1557. ', '.join(sorted(kwargs)))
  1558. return self._join(props,
  1559. outerjoin=isouter, full=full,
  1560. create_aliases=aliased,
  1561. from_joinpoint=from_joinpoint)
  1562. def outerjoin(self, *props, **kwargs):
  1563. """Create a left outer join against this ``Query`` object's criterion
  1564. and apply generatively, returning the newly resulting ``Query``.
  1565. Usage is the same as the ``join()`` method.
  1566. """
  1567. aliased, from_joinpoint, full = kwargs.pop('aliased', False), \
  1568. kwargs.pop('from_joinpoint', False), \
  1569. kwargs.pop('full', False)
  1570. if kwargs:
  1571. raise TypeError("unknown arguments: %s" %
  1572. ', '.join(sorted(kwargs)))
  1573. return self._join(props,
  1574. outerjoin=True, full=full, create_aliases=aliased,
  1575. from_joinpoint=from_joinpoint)
  1576. def _update_joinpoint(self, jp):
  1577. self._joinpoint = jp
  1578. # copy backwards to the root of the _joinpath
  1579. # dict, so that no existing dict in the path is mutated
  1580. while 'prev' in jp:
  1581. f, prev = jp['prev']
  1582. prev = prev.copy()
  1583. prev[f] = jp
  1584. jp['prev'] = (f, prev)
  1585. jp = prev
  1586. self._joinpath = jp
  1587. @_generative(_no_statement_condition, _no_limit_offset)
  1588. def _join(self, keys, outerjoin, full, create_aliases, from_joinpoint):
  1589. """consumes arguments from join() or outerjoin(), places them into a
  1590. consistent format with which to form the actual JOIN constructs.
  1591. """
  1592. if not from_joinpoint:
  1593. self._reset_joinpoint()
  1594. if len(keys) == 2 and \
  1595. isinstance(keys[0], (expression.FromClause,
  1596. type, AliasedClass)) and \
  1597. isinstance(keys[1], (str, expression.ClauseElement,
  1598. interfaces.PropComparator)):
  1599. # detect 2-arg form of join and
  1600. # convert to a tuple.
  1601. keys = (keys,)
  1602. keylist = util.to_list(keys)
  1603. for idx, arg1 in enumerate(keylist):
  1604. if isinstance(arg1, tuple):
  1605. # "tuple" form of join, multiple
  1606. # tuples are accepted as well. The simpler
  1607. # "2-arg" form is preferred. May deprecate
  1608. # the "tuple" usage.
  1609. arg1, arg2 = arg1
  1610. else:
  1611. arg2 = None
  1612. # determine onclause/right_entity. there
  1613. # is a little bit of legacy behavior still at work here
  1614. # which means they might be in either order. may possibly
  1615. # lock this down to (right_entity, onclause) in 0.6.
  1616. if isinstance(
  1617. arg1, (interfaces.PropComparator, util.string_types)):
  1618. right_entity, onclause = arg2, arg1
  1619. else:
  1620. right_entity, onclause = arg1, arg2
  1621. left_entity = prop = None
  1622. if isinstance(onclause, interfaces.PropComparator):
  1623. of_type = getattr(onclause, '_of_type', None)
  1624. else:
  1625. of_type = None
  1626. if isinstance(onclause, util.string_types):
  1627. left_entity = self._joinpoint_zero()
  1628. descriptor = _entity_descriptor(left_entity, onclause)
  1629. onclause = descriptor
  1630. # check for q.join(Class.propname, from_joinpoint=True)
  1631. # and Class is that of the current joinpoint
  1632. elif from_joinpoint and \
  1633. isinstance(onclause, interfaces.PropComparator):
  1634. left_entity = onclause._parententity
  1635. info = inspect(self._joinpoint_zero())
  1636. left_mapper, left_selectable, left_is_aliased = \
  1637. getattr(info, 'mapper', None), \
  1638. info.selectable, \
  1639. getattr(info, 'is_aliased_class', None)
  1640. if left_mapper is left_entity:
  1641. left_entity = self._joinpoint_zero()
  1642. descriptor = _entity_descriptor(left_entity,
  1643. onclause.key)
  1644. onclause = descriptor
  1645. if isinstance(onclause, interfaces.PropComparator):
  1646. if right_entity is None:
  1647. if of_type:
  1648. right_entity = of_type
  1649. else:
  1650. right_entity = onclause.property.mapper
  1651. left_entity = onclause._parententity
  1652. prop = onclause.property
  1653. if not isinstance(onclause, attributes.QueryableAttribute):
  1654. onclause = prop
  1655. if not create_aliases:
  1656. # check for this path already present.
  1657. # don't render in that case.
  1658. edge = (left_entity, right_entity, prop.key)
  1659. if edge in self._joinpoint:
  1660. # The child's prev reference might be stale --
  1661. # it could point to a parent older than the
  1662. # current joinpoint. If this is the case,
  1663. # then we need to update it and then fix the
  1664. # tree's spine with _update_joinpoint. Copy
  1665. # and then mutate the child, which might be
  1666. # shared by a different query object.
  1667. jp = self._joinpoint[edge].copy()
  1668. jp['prev'] = (edge, self._joinpoint)
  1669. self._update_joinpoint(jp)
  1670. if idx == len(keylist) - 1:
  1671. util.warn(
  1672. "Pathed join target %s has already "
  1673. "been joined to; skipping" % prop)
  1674. continue
  1675. elif onclause is not None and right_entity is None:
  1676. # TODO: no coverage here
  1677. raise NotImplementedError("query.join(a==b) not supported.")
  1678. self._join_left_to_right(
  1679. left_entity,
  1680. right_entity, onclause,
  1681. outerjoin, full, create_aliases, prop)
  1682. def _join_left_to_right(self, left, right,
  1683. onclause, outerjoin, full, create_aliases, prop):
  1684. """append a JOIN to the query's from clause."""
  1685. self._polymorphic_adapters = self._polymorphic_adapters.copy()
  1686. if left is None:
  1687. if self._from_obj:
  1688. left = self._from_obj[0]
  1689. elif self._entities:
  1690. left = self._entities[0].entity_zero_or_selectable
  1691. if left is None:
  1692. if self._entities:
  1693. problem = "Don't know how to join from %s" % self._entities[0]
  1694. else:
  1695. problem = "No entities to join from"
  1696. raise sa_exc.InvalidRequestError(
  1697. "%s; please use "
  1698. "select_from() to establish the left "
  1699. "entity/selectable of this join" % problem)
  1700. if left is right and \
  1701. not create_aliases:
  1702. raise sa_exc.InvalidRequestError(
  1703. "Can't construct a join from %s to %s, they "
  1704. "are the same entity" %
  1705. (left, right))
  1706. l_info = inspect(left)
  1707. r_info = inspect(right)
  1708. overlap = False
  1709. if not create_aliases:
  1710. right_mapper = getattr(r_info, "mapper", None)
  1711. # if the target is a joined inheritance mapping,
  1712. # be more liberal about auto-aliasing.
  1713. if right_mapper and (
  1714. right_mapper.with_polymorphic or
  1715. isinstance(right_mapper.mapped_table, expression.Join)
  1716. ):
  1717. for from_obj in self._from_obj or [l_info.selectable]:
  1718. if sql_util.selectables_overlap(
  1719. l_info.selectable, from_obj) and \
  1720. sql_util.selectables_overlap(
  1721. from_obj, r_info.selectable):
  1722. overlap = True
  1723. break
  1724. if (overlap or not create_aliases) and \
  1725. l_info.selectable is r_info.selectable:
  1726. raise sa_exc.InvalidRequestError(
  1727. "Can't join table/selectable '%s' to itself" %
  1728. l_info.selectable)
  1729. right, onclause = self._prepare_right_side(
  1730. r_info, right, onclause,
  1731. create_aliases,
  1732. prop, overlap)
  1733. # if joining on a MapperProperty path,
  1734. # track the path to prevent redundant joins
  1735. if not create_aliases and prop:
  1736. self._update_joinpoint({
  1737. '_joinpoint_entity': right,
  1738. 'prev': ((left, right, prop.key), self._joinpoint)
  1739. })
  1740. else:
  1741. self._joinpoint = {'_joinpoint_entity': right}
  1742. self._join_to_left(l_info, left, right, onclause, outerjoin, full)
  1743. def _prepare_right_side(self, r_info, right, onclause, create_aliases,
  1744. prop, overlap):
  1745. info = r_info
  1746. right_mapper, right_selectable, right_is_aliased = \
  1747. getattr(info, 'mapper', None), \
  1748. info.selectable, \
  1749. getattr(info, 'is_aliased_class', False)
  1750. if right_mapper:
  1751. self._join_entities += (info, )
  1752. if right_mapper and prop and \
  1753. not right_mapper.common_parent(prop.mapper):
  1754. raise sa_exc.InvalidRequestError(
  1755. "Join target %s does not correspond to "
  1756. "the right side of join condition %s" % (right, onclause)
  1757. )
  1758. if not right_mapper and prop:
  1759. right_mapper = prop.mapper
  1760. need_adapter = False
  1761. if right_mapper and right is right_selectable:
  1762. if not right_selectable.is_derived_from(
  1763. right_mapper.mapped_table):
  1764. raise sa_exc.InvalidRequestError(
  1765. "Selectable '%s' is not derived from '%s'" %
  1766. (right_selectable.description,
  1767. right_mapper.mapped_table.description))
  1768. if isinstance(right_selectable, expression.SelectBase):
  1769. # TODO: this isn't even covered now!
  1770. right_selectable = right_selectable.alias()
  1771. need_adapter = True
  1772. right = aliased(right_mapper, right_selectable)
  1773. aliased_entity = right_mapper and \
  1774. not right_is_aliased and \
  1775. (
  1776. right_mapper.with_polymorphic and isinstance(
  1777. right_mapper._with_polymorphic_selectable,
  1778. expression.Alias)
  1779. or
  1780. overlap # test for overlap:
  1781. # orm/inheritance/relationships.py
  1782. # SelfReferentialM2MTest
  1783. )
  1784. if not need_adapter and (create_aliases or aliased_entity):
  1785. right = aliased(right, flat=True)
  1786. need_adapter = True
  1787. # if an alias() of the right side was generated here,
  1788. # apply an adapter to all subsequent filter() calls
  1789. # until reset_joinpoint() is called.
  1790. if need_adapter:
  1791. self._filter_aliases = ORMAdapter(
  1792. right,
  1793. equivalents=right_mapper and
  1794. right_mapper._equivalent_columns or {},
  1795. chain_to=self._filter_aliases)
  1796. # if the onclause is a ClauseElement, adapt it with any
  1797. # adapters that are in place right now
  1798. if isinstance(onclause, expression.ClauseElement):
  1799. onclause = self._adapt_clause(onclause, True, True)
  1800. # if an alias() on the right side was generated,
  1801. # which is intended to wrap a the right side in a subquery,
  1802. # ensure that columns retrieved from this target in the result
  1803. # set are also adapted.
  1804. if aliased_entity and not create_aliases:
  1805. self._mapper_loads_polymorphically_with(
  1806. right_mapper,
  1807. ORMAdapter(
  1808. right,
  1809. equivalents=right_mapper._equivalent_columns
  1810. )
  1811. )
  1812. return right, onclause
  1813. def _join_to_left(self, l_info, left, right, onclause, outerjoin, full):
  1814. info = l_info
  1815. left_mapper = getattr(info, 'mapper', None)
  1816. left_selectable = info.selectable
  1817. if self._from_obj:
  1818. replace_clause_index, clause = sql_util.find_join_source(
  1819. self._from_obj,
  1820. left_selectable)
  1821. if clause is not None:
  1822. try:
  1823. clause = orm_join(clause,
  1824. right,
  1825. onclause, isouter=outerjoin, full=full)
  1826. except sa_exc.ArgumentError as ae:
  1827. raise sa_exc.InvalidRequestError(
  1828. "Could not find a FROM clause to join from. "
  1829. "Tried joining to %s, but got: %s" % (right, ae))
  1830. self._from_obj = \
  1831. self._from_obj[:replace_clause_index] + \
  1832. (clause, ) + \
  1833. self._from_obj[replace_clause_index + 1:]
  1834. return
  1835. if left_mapper:
  1836. for ent in self._entities:
  1837. if ent.corresponds_to(left):
  1838. clause = ent.selectable
  1839. break
  1840. else:
  1841. clause = left
  1842. else:
  1843. clause = left_selectable
  1844. assert clause is not None
  1845. try:
  1846. clause = orm_join(
  1847. clause, right, onclause, isouter=outerjoin, full=full)
  1848. except sa_exc.ArgumentError as ae:
  1849. raise sa_exc.InvalidRequestError(
  1850. "Could not find a FROM clause to join from. "
  1851. "Tried joining to %s, but got: %s" % (right, ae))
  1852. self._from_obj = self._from_obj + (clause,)
  1853. def _reset_joinpoint(self):
  1854. self._joinpoint = self._joinpath
  1855. self._filter_aliases = None
  1856. @_generative(_no_statement_condition)
  1857. def reset_joinpoint(self):
  1858. """Return a new :class:`.Query`, where the "join point" has
  1859. been reset back to the base FROM entities of the query.
  1860. This method is usually used in conjunction with the
  1861. ``aliased=True`` feature of the :meth:`~.Query.join`
  1862. method. See the example in :meth:`~.Query.join` for how
  1863. this is used.
  1864. """
  1865. self._reset_joinpoint()
  1866. @_generative(_no_clauseelement_condition)
  1867. def select_from(self, *from_obj):
  1868. r"""Set the FROM clause of this :class:`.Query` explicitly.
  1869. :meth:`.Query.select_from` is often used in conjunction with
  1870. :meth:`.Query.join` in order to control which entity is selected
  1871. from on the "left" side of the join.
  1872. The entity or selectable object here effectively replaces the
  1873. "left edge" of any calls to :meth:`~.Query.join`, when no
  1874. joinpoint is otherwise established - usually, the default "join
  1875. point" is the leftmost entity in the :class:`~.Query` object's
  1876. list of entities to be selected.
  1877. A typical example::
  1878. q = session.query(Address).select_from(User).\
  1879. join(User.addresses).\
  1880. filter(User.name == 'ed')
  1881. Which produces SQL equivalent to::
  1882. SELECT address.* FROM user
  1883. JOIN address ON user.id=address.user_id
  1884. WHERE user.name = :name_1
  1885. :param \*from_obj: collection of one or more entities to apply
  1886. to the FROM clause. Entities can be mapped classes,
  1887. :class:`.AliasedClass` objects, :class:`.Mapper` objects
  1888. as well as core :class:`.FromClause` elements like subqueries.
  1889. .. versionchanged:: 0.9
  1890. This method no longer applies the given FROM object
  1891. to be the selectable from which matching entities
  1892. select from; the :meth:`.select_entity_from` method
  1893. now accomplishes this. See that method for a description
  1894. of this behavior.
  1895. .. seealso::
  1896. :meth:`~.Query.join`
  1897. :meth:`.Query.select_entity_from`
  1898. """
  1899. self._set_select_from(from_obj, False)
  1900. @_generative(_no_clauseelement_condition)
  1901. def select_entity_from(self, from_obj):
  1902. r"""Set the FROM clause of this :class:`.Query` to a
  1903. core selectable, applying it as a replacement FROM clause
  1904. for corresponding mapped entities.
  1905. The :meth:`.Query.select_entity_from` method supplies an alternative
  1906. approach to the use case of applying an :func:`.aliased` construct
  1907. explicitly throughout a query. Instead of referring to the
  1908. :func:`.aliased` construct explicitly,
  1909. :meth:`.Query.select_entity_from` automatically *adapts* all occurences
  1910. of the entity to the target selectable.
  1911. Given a case for :func:`.aliased` such as selecting ``User``
  1912. objects from a SELECT statement::
  1913. select_stmt = select([User]).where(User.id == 7)
  1914. user_alias = aliased(User, select_stmt)
  1915. q = session.query(user_alias).\
  1916. filter(user_alias.name == 'ed')
  1917. Above, we apply the ``user_alias`` object explicitly throughout the
  1918. query. When it's not feasible for ``user_alias`` to be referenced
  1919. explicitly in many places, :meth:`.Query.select_entity_from` may be
  1920. used at the start of the query to adapt the existing ``User`` entity::
  1921. q = session.query(User).\
  1922. select_entity_from(select_stmt).\
  1923. filter(User.name == 'ed')
  1924. Above, the generated SQL will show that the ``User`` entity is
  1925. adapted to our statement, even in the case of the WHERE clause:
  1926. .. sourcecode:: sql
  1927. SELECT anon_1.id AS anon_1_id, anon_1.name AS anon_1_name
  1928. FROM (SELECT "user".id AS id, "user".name AS name
  1929. FROM "user"
  1930. WHERE "user".id = :id_1) AS anon_1
  1931. WHERE anon_1.name = :name_1
  1932. The :meth:`.Query.select_entity_from` method is similar to the
  1933. :meth:`.Query.select_from` method, in that it sets the FROM clause
  1934. of the query. The difference is that it additionally applies
  1935. adaptation to the other parts of the query that refer to the
  1936. primary entity. If above we had used :meth:`.Query.select_from`
  1937. instead, the SQL generated would have been:
  1938. .. sourcecode:: sql
  1939. -- uses plain select_from(), not select_entity_from()
  1940. SELECT "user".id AS user_id, "user".name AS user_name
  1941. FROM "user", (SELECT "user".id AS id, "user".name AS name
  1942. FROM "user"
  1943. WHERE "user".id = :id_1) AS anon_1
  1944. WHERE "user".name = :name_1
  1945. To supply textual SQL to the :meth:`.Query.select_entity_from` method,
  1946. we can make use of the :func:`.text` construct. However, the
  1947. :func:`.text` construct needs to be aligned with the columns of our
  1948. entity, which is achieved by making use of the
  1949. :meth:`.TextClause.columns` method::
  1950. text_stmt = text("select id, name from user").columns(
  1951. User.id, User.name)
  1952. q = session.query(User).select_entity_from(text_stmt)
  1953. :meth:`.Query.select_entity_from` itself accepts an :func:`.aliased`
  1954. object, so that the special options of :func:`.aliased` such as
  1955. :paramref:`.aliased.adapt_on_names` may be used within the
  1956. scope of the :meth:`.Query.select_entity_from` method's adaptation
  1957. services. Suppose
  1958. a view ``user_view`` also returns rows from ``user``. If
  1959. we reflect this view into a :class:`.Table`, this view has no
  1960. relationship to the :class:`.Table` to which we are mapped, however
  1961. we can use name matching to select from it::
  1962. user_view = Table('user_view', metadata,
  1963. autoload_with=engine)
  1964. user_view_alias = aliased(
  1965. User, user_view, adapt_on_names=True)
  1966. q = session.query(User).\
  1967. select_entity_from(user_view_alias).\
  1968. order_by(User.name)
  1969. .. versionchanged:: 1.1.7 The :meth:`.Query.select_entity_from`
  1970. method now accepts an :func:`.aliased` object as an alternative
  1971. to a :class:`.FromClause` object.
  1972. :param from_obj: a :class:`.FromClause` object that will replace
  1973. the FROM clause of this :class:`.Query`. It also may be an instance
  1974. of :func:`.aliased`.
  1975. .. seealso::
  1976. :meth:`.Query.select_from`
  1977. """
  1978. self._set_select_from([from_obj], True)
  1979. def __getitem__(self, item):
  1980. if isinstance(item, slice):
  1981. start, stop, step = util.decode_slice(item)
  1982. if isinstance(stop, int) and \
  1983. isinstance(start, int) and \
  1984. stop - start <= 0:
  1985. return []
  1986. # perhaps we should execute a count() here so that we
  1987. # can still use LIMIT/OFFSET ?
  1988. elif (isinstance(start, int) and start < 0) \
  1989. or (isinstance(stop, int) and stop < 0):
  1990. return list(self)[item]
  1991. res = self.slice(start, stop)
  1992. if step is not None:
  1993. return list(res)[None:None:item.step]
  1994. else:
  1995. return list(res)
  1996. else:
  1997. if item == -1:
  1998. return list(self)[-1]
  1999. else:
  2000. return list(self[item:item + 1])[0]
  2001. @_generative(_no_statement_condition)
  2002. def slice(self, start, stop):
  2003. """Computes the "slice" of the :class:`.Query` represented by
  2004. the given indices and returns the resulting :class:`.Query`.
  2005. The start and stop indices behave like the argument to Python's
  2006. built-in :func:`range` function. This method provides an
  2007. alternative to using ``LIMIT``/``OFFSET`` to get a slice of the
  2008. query.
  2009. For example, ::
  2010. session.query(User).order_by(User.id).slice(1, 3)
  2011. renders as
  2012. .. sourcecode:: sql
  2013. SELECT users.id AS users_id,
  2014. users.name AS users_name
  2015. FROM users ORDER BY users.id
  2016. LIMIT ? OFFSET ?
  2017. (2, 1)
  2018. .. seealso::
  2019. :meth:`.Query.limit`
  2020. :meth:`.Query.offset`
  2021. """
  2022. if start is not None and stop is not None:
  2023. self._offset = (self._offset or 0) + start
  2024. self._limit = stop - start
  2025. elif start is None and stop is not None:
  2026. self._limit = stop
  2027. elif start is not None and stop is None:
  2028. self._offset = (self._offset or 0) + start
  2029. if self._offset == 0:
  2030. self._offset = None
  2031. @_generative(_no_statement_condition)
  2032. def limit(self, limit):
  2033. """Apply a ``LIMIT`` to the query and return the newly resulting
  2034. ``Query``.
  2035. """
  2036. self._limit = limit
  2037. @_generative(_no_statement_condition)
  2038. def offset(self, offset):
  2039. """Apply an ``OFFSET`` to the query and return the newly resulting
  2040. ``Query``.
  2041. """
  2042. self._offset = offset
  2043. @_generative(_no_statement_condition)
  2044. def distinct(self, *criterion):
  2045. r"""Apply a ``DISTINCT`` to the query and return the newly resulting
  2046. ``Query``.
  2047. .. note::
  2048. The :meth:`.distinct` call includes logic that will automatically
  2049. add columns from the ORDER BY of the query to the columns
  2050. clause of the SELECT statement, to satisfy the common need
  2051. of the database backend that ORDER BY columns be part of the
  2052. SELECT list when DISTINCT is used. These columns *are not*
  2053. added to the list of columns actually fetched by the
  2054. :class:`.Query`, however, so would not affect results.
  2055. The columns are passed through when using the
  2056. :attr:`.Query.statement` accessor, however.
  2057. :param \*expr: optional column expressions. When present,
  2058. the PostgreSQL dialect will render a ``DISTINCT ON (<expressions>>)``
  2059. construct.
  2060. """
  2061. if not criterion:
  2062. self._distinct = True
  2063. else:
  2064. criterion = self._adapt_col_list(criterion)
  2065. if isinstance(self._distinct, list):
  2066. self._distinct += criterion
  2067. else:
  2068. self._distinct = criterion
  2069. @_generative()
  2070. def prefix_with(self, *prefixes):
  2071. r"""Apply the prefixes to the query and return the newly resulting
  2072. ``Query``.
  2073. :param \*prefixes: optional prefixes, typically strings,
  2074. not using any commas. In particular is useful for MySQL keywords.
  2075. e.g.::
  2076. query = sess.query(User.name).\
  2077. prefix_with('HIGH_PRIORITY').\
  2078. prefix_with('SQL_SMALL_RESULT', 'ALL')
  2079. Would render::
  2080. SELECT HIGH_PRIORITY SQL_SMALL_RESULT ALL users.name AS users_name
  2081. FROM users
  2082. .. versionadded:: 0.7.7
  2083. .. seealso::
  2084. :meth:`.HasPrefixes.prefix_with`
  2085. """
  2086. if self._prefixes:
  2087. self._prefixes += prefixes
  2088. else:
  2089. self._prefixes = prefixes
  2090. @_generative()
  2091. def suffix_with(self, *suffixes):
  2092. r"""Apply the suffix to the query and return the newly resulting
  2093. ``Query``.
  2094. :param \*suffixes: optional suffixes, typically strings,
  2095. not using any commas.
  2096. .. versionadded:: 1.0.0
  2097. .. seealso::
  2098. :meth:`.Query.prefix_with`
  2099. :meth:`.HasSuffixes.suffix_with`
  2100. """
  2101. if self._suffixes:
  2102. self._suffixes += suffixes
  2103. else:
  2104. self._suffixes = suffixes
  2105. def all(self):
  2106. """Return the results represented by this ``Query`` as a list.
  2107. This results in an execution of the underlying query.
  2108. """
  2109. return list(self)
  2110. @_generative(_no_clauseelement_condition)
  2111. def from_statement(self, statement):
  2112. """Execute the given SELECT statement and return results.
  2113. This method bypasses all internal statement compilation, and the
  2114. statement is executed without modification.
  2115. The statement is typically either a :func:`~.expression.text`
  2116. or :func:`~.expression.select` construct, and should return the set
  2117. of columns
  2118. appropriate to the entity class represented by this :class:`.Query`.
  2119. .. seealso::
  2120. :ref:`orm_tutorial_literal_sql` - usage examples in the
  2121. ORM tutorial
  2122. """
  2123. statement = expression._expression_literal_as_text(statement)
  2124. if not isinstance(statement,
  2125. (expression.TextClause,
  2126. expression.SelectBase)):
  2127. raise sa_exc.ArgumentError(
  2128. "from_statement accepts text(), select(), "
  2129. "and union() objects only.")
  2130. self._statement = statement
  2131. def first(self):
  2132. """Return the first result of this ``Query`` or
  2133. None if the result doesn't contain any row.
  2134. first() applies a limit of one within the generated SQL, so that
  2135. only one primary entity row is generated on the server side
  2136. (note this may consist of multiple result rows if join-loaded
  2137. collections are present).
  2138. Calling :meth:`.Query.first` results in an execution of the underlying query.
  2139. .. seealso::
  2140. :meth:`.Query.one`
  2141. :meth:`.Query.one_or_none`
  2142. """
  2143. if self._statement is not None:
  2144. ret = list(self)[0:1]
  2145. else:
  2146. ret = list(self[0:1])
  2147. if len(ret) > 0:
  2148. return ret[0]
  2149. else:
  2150. return None
  2151. def one_or_none(self):
  2152. """Return at most one result or raise an exception.
  2153. Returns ``None`` if the query selects
  2154. no rows. Raises ``sqlalchemy.orm.exc.MultipleResultsFound``
  2155. if multiple object identities are returned, or if multiple
  2156. rows are returned for a query that returns only scalar values
  2157. as opposed to full identity-mapped entities.
  2158. Calling :meth:`.Query.one_or_none` results in an execution of the
  2159. underlying query.
  2160. .. versionadded:: 1.0.9
  2161. Added :meth:`.Query.one_or_none`
  2162. .. seealso::
  2163. :meth:`.Query.first`
  2164. :meth:`.Query.one`
  2165. """
  2166. ret = list(self)
  2167. l = len(ret)
  2168. if l == 1:
  2169. return ret[0]
  2170. elif l == 0:
  2171. return None
  2172. else:
  2173. raise orm_exc.MultipleResultsFound(
  2174. "Multiple rows were found for one_or_none()")
  2175. def one(self):
  2176. """Return exactly one result or raise an exception.
  2177. Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
  2178. no rows. Raises ``sqlalchemy.orm.exc.MultipleResultsFound``
  2179. if multiple object identities are returned, or if multiple
  2180. rows are returned for a query that returns only scalar values
  2181. as opposed to full identity-mapped entities.
  2182. Calling :meth:`.one` results in an execution of the underlying query.
  2183. .. seealso::
  2184. :meth:`.Query.first`
  2185. :meth:`.Query.one_or_none`
  2186. """
  2187. try:
  2188. ret = self.one_or_none()
  2189. except orm_exc.MultipleResultsFound:
  2190. raise orm_exc.MultipleResultsFound(
  2191. "Multiple rows were found for one()")
  2192. else:
  2193. if ret is None:
  2194. raise orm_exc.NoResultFound("No row was found for one()")
  2195. return ret
  2196. def scalar(self):
  2197. """Return the first element of the first result or None
  2198. if no rows present. If multiple rows are returned,
  2199. raises MultipleResultsFound.
  2200. >>> session.query(Item).scalar()
  2201. <Item>
  2202. >>> session.query(Item.id).scalar()
  2203. 1
  2204. >>> session.query(Item.id).filter(Item.id < 0).scalar()
  2205. None
  2206. >>> session.query(Item.id, Item.name).scalar()
  2207. 1
  2208. >>> session.query(func.count(Parent.id)).scalar()
  2209. 20
  2210. This results in an execution of the underlying query.
  2211. """
  2212. try:
  2213. ret = self.one()
  2214. if not isinstance(ret, tuple):
  2215. return ret
  2216. return ret[0]
  2217. except orm_exc.NoResultFound:
  2218. return None
  2219. def __iter__(self):
  2220. context = self._compile_context()
  2221. context.statement.use_labels = True
  2222. if self._autoflush and not self._populate_existing:
  2223. self.session._autoflush()
  2224. return self._execute_and_instances(context)
  2225. def __str__(self):
  2226. context = self._compile_context()
  2227. try:
  2228. bind = self._get_bind_args(
  2229. context, self.session.get_bind) if self.session else None
  2230. except sa_exc.UnboundExecutionError:
  2231. bind = None
  2232. return str(context.statement.compile(bind))
  2233. def _connection_from_session(self, **kw):
  2234. conn = self.session.connection(**kw)
  2235. if self._execution_options:
  2236. conn = conn.execution_options(**self._execution_options)
  2237. return conn
  2238. def _execute_and_instances(self, querycontext):
  2239. conn = self._get_bind_args(
  2240. querycontext,
  2241. self._connection_from_session,
  2242. close_with_result=True)
  2243. result = conn.execute(querycontext.statement, self._params)
  2244. return loading.instances(querycontext.query, result, querycontext)
  2245. def _get_bind_args(self, querycontext, fn, **kw):
  2246. return fn(
  2247. mapper=self._bind_mapper(),
  2248. clause=querycontext.statement,
  2249. **kw
  2250. )
  2251. @property
  2252. def column_descriptions(self):
  2253. """Return metadata about the columns which would be
  2254. returned by this :class:`.Query`.
  2255. Format is a list of dictionaries::
  2256. user_alias = aliased(User, name='user2')
  2257. q = sess.query(User, User.id, user_alias)
  2258. # this expression:
  2259. q.column_descriptions
  2260. # would return:
  2261. [
  2262. {
  2263. 'name':'User',
  2264. 'type':User,
  2265. 'aliased':False,
  2266. 'expr':User,
  2267. 'entity': User
  2268. },
  2269. {
  2270. 'name':'id',
  2271. 'type':Integer(),
  2272. 'aliased':False,
  2273. 'expr':User.id,
  2274. 'entity': User
  2275. },
  2276. {
  2277. 'name':'user2',
  2278. 'type':User,
  2279. 'aliased':True,
  2280. 'expr':user_alias,
  2281. 'entity': user_alias
  2282. }
  2283. ]
  2284. """
  2285. return [
  2286. {
  2287. 'name': ent._label_name,
  2288. 'type': ent.type,
  2289. 'aliased': getattr(insp_ent, 'is_aliased_class', False),
  2290. 'expr': ent.expr,
  2291. 'entity':
  2292. getattr(insp_ent, "entity", None)
  2293. if ent.entity_zero is not None
  2294. and not insp_ent.is_clause_element
  2295. else None
  2296. }
  2297. for ent, insp_ent in [
  2298. (
  2299. _ent,
  2300. (inspect(_ent.entity_zero)
  2301. if _ent.entity_zero is not None else None)
  2302. )
  2303. for _ent in self._entities
  2304. ]
  2305. ]
  2306. def instances(self, cursor, __context=None):
  2307. """Given a ResultProxy cursor as returned by connection.execute(),
  2308. return an ORM result as an iterator.
  2309. e.g.::
  2310. result = engine.execute("select * from users")
  2311. for u in session.query(User).instances(result):
  2312. print u
  2313. """
  2314. context = __context
  2315. if context is None:
  2316. context = QueryContext(self)
  2317. return loading.instances(self, cursor, context)
  2318. def merge_result(self, iterator, load=True):
  2319. """Merge a result into this :class:`.Query` object's Session.
  2320. Given an iterator returned by a :class:`.Query` of the same structure
  2321. as this one, return an identical iterator of results, with all mapped
  2322. instances merged into the session using :meth:`.Session.merge`. This
  2323. is an optimized method which will merge all mapped instances,
  2324. preserving the structure of the result rows and unmapped columns with
  2325. less method overhead than that of calling :meth:`.Session.merge`
  2326. explicitly for each value.
  2327. The structure of the results is determined based on the column list of
  2328. this :class:`.Query` - if these do not correspond, unchecked errors
  2329. will occur.
  2330. The 'load' argument is the same as that of :meth:`.Session.merge`.
  2331. For an example of how :meth:`~.Query.merge_result` is used, see
  2332. the source code for the example :ref:`examples_caching`, where
  2333. :meth:`~.Query.merge_result` is used to efficiently restore state
  2334. from a cache back into a target :class:`.Session`.
  2335. """
  2336. return loading.merge_result(self, iterator, load)
  2337. @property
  2338. def _select_args(self):
  2339. return {
  2340. 'limit': self._limit,
  2341. 'offset': self._offset,
  2342. 'distinct': self._distinct,
  2343. 'prefixes': self._prefixes,
  2344. 'suffixes': self._suffixes,
  2345. 'group_by': self._group_by or None,
  2346. 'having': self._having
  2347. }
  2348. @property
  2349. def _should_nest_selectable(self):
  2350. kwargs = self._select_args
  2351. return (kwargs.get('limit') is not None or
  2352. kwargs.get('offset') is not None or
  2353. kwargs.get('distinct', False))
  2354. def exists(self):
  2355. """A convenience method that turns a query into an EXISTS subquery
  2356. of the form EXISTS (SELECT 1 FROM ... WHERE ...).
  2357. e.g.::
  2358. q = session.query(User).filter(User.name == 'fred')
  2359. session.query(q.exists())
  2360. Producing SQL similar to::
  2361. SELECT EXISTS (
  2362. SELECT 1 FROM users WHERE users.name = :name_1
  2363. ) AS anon_1
  2364. The EXISTS construct is usually used in the WHERE clause::
  2365. session.query(User.id).filter(q.exists()).scalar()
  2366. Note that some databases such as SQL Server don't allow an
  2367. EXISTS expression to be present in the columns clause of a
  2368. SELECT. To select a simple boolean value based on the exists
  2369. as a WHERE, use :func:`.literal`::
  2370. from sqlalchemy import literal
  2371. session.query(literal(True)).filter(q.exists()).scalar()
  2372. .. versionadded:: 0.8.1
  2373. """
  2374. # .add_columns() for the case that we are a query().select_from(X),
  2375. # so that ".statement" can be produced (#2995) but also without
  2376. # omitting the FROM clause from a query(X) (#2818);
  2377. # .with_only_columns() after we have a core select() so that
  2378. # we get just "SELECT 1" without any entities.
  2379. return sql.exists(self.add_columns('1').with_labels().
  2380. statement.with_only_columns([1]))
  2381. def count(self):
  2382. r"""Return a count of rows this Query would return.
  2383. This generates the SQL for this Query as follows::
  2384. SELECT count(1) AS count_1 FROM (
  2385. SELECT <rest of query follows...>
  2386. ) AS anon_1
  2387. .. versionchanged:: 0.7
  2388. The above scheme is newly refined as of 0.7b3.
  2389. For fine grained control over specific columns
  2390. to count, to skip the usage of a subquery or
  2391. otherwise control of the FROM clause,
  2392. or to use other aggregate functions,
  2393. use :attr:`~sqlalchemy.sql.expression.func`
  2394. expressions in conjunction
  2395. with :meth:`~.Session.query`, i.e.::
  2396. from sqlalchemy import func
  2397. # count User records, without
  2398. # using a subquery.
  2399. session.query(func.count(User.id))
  2400. # return count of user "id" grouped
  2401. # by "name"
  2402. session.query(func.count(User.id)).\
  2403. group_by(User.name)
  2404. from sqlalchemy import distinct
  2405. # count distinct "name" values
  2406. session.query(func.count(distinct(User.name)))
  2407. """
  2408. col = sql.func.count(sql.literal_column('*'))
  2409. return self.from_self(col).scalar()
  2410. def delete(self, synchronize_session='evaluate'):
  2411. r"""Perform a bulk delete query.
  2412. Deletes rows matched by this query from the database.
  2413. E.g.::
  2414. sess.query(User).filter(User.age == 25).\
  2415. delete(synchronize_session=False)
  2416. sess.query(User).filter(User.age == 25).\
  2417. delete(synchronize_session='evaluate')
  2418. .. warning:: The :meth:`.Query.delete` method is a "bulk" operation,
  2419. which bypasses ORM unit-of-work automation in favor of greater
  2420. performance. **Please read all caveats and warnings below.**
  2421. :param synchronize_session: chooses the strategy for the removal of
  2422. matched objects from the session. Valid values are:
  2423. ``False`` - don't synchronize the session. This option is the most
  2424. efficient and is reliable once the session is expired, which
  2425. typically occurs after a commit(), or explicitly using
  2426. expire_all(). Before the expiration, objects may still remain in
  2427. the session which were in fact deleted which can lead to confusing
  2428. results if they are accessed via get() or already loaded
  2429. collections.
  2430. ``'fetch'`` - performs a select query before the delete to find
  2431. objects that are matched by the delete query and need to be
  2432. removed from the session. Matched objects are removed from the
  2433. session.
  2434. ``'evaluate'`` - Evaluate the query's criteria in Python straight
  2435. on the objects in the session. If evaluation of the criteria isn't
  2436. implemented, an error is raised.
  2437. The expression evaluator currently doesn't account for differing
  2438. string collations between the database and Python.
  2439. :return: the count of rows matched as returned by the database's
  2440. "row count" feature.
  2441. .. warning:: **Additional Caveats for bulk query deletes**
  2442. * This method does **not work for joined
  2443. inheritance mappings**, since the **multiple table
  2444. deletes are not supported by SQL** as well as that the
  2445. **join condition of an inheritance mapper is not
  2446. automatically rendered**. Care must be taken in any
  2447. multiple-table delete to first accommodate via some other means
  2448. how the related table will be deleted, as well as to
  2449. explicitly include the joining
  2450. condition between those tables, even in mappings where
  2451. this is normally automatic. E.g. if a class ``Engineer``
  2452. subclasses ``Employee``, a DELETE against the ``Employee``
  2453. table would look like::
  2454. session.query(Engineer).\
  2455. filter(Engineer.id == Employee.id).\
  2456. filter(Employee.name == 'dilbert').\
  2457. delete()
  2458. However the above SQL will not delete from the Engineer table,
  2459. unless an ON DELETE CASCADE rule is established in the database
  2460. to handle it.
  2461. Short story, **do not use this method for joined inheritance
  2462. mappings unless you have taken the additional steps to make
  2463. this feasible**.
  2464. * The polymorphic identity WHERE criteria is **not** included
  2465. for single- or
  2466. joined- table updates - this must be added **manually** even
  2467. for single table inheritance.
  2468. * The method does **not** offer in-Python cascading of
  2469. relationships - it is assumed that ON DELETE CASCADE/SET
  2470. NULL/etc. is configured for any foreign key references
  2471. which require it, otherwise the database may emit an
  2472. integrity violation if foreign key references are being
  2473. enforced.
  2474. After the DELETE, dependent objects in the
  2475. :class:`.Session` which were impacted by an ON DELETE
  2476. may not contain the current state, or may have been
  2477. deleted. This issue is resolved once the
  2478. :class:`.Session` is expired, which normally occurs upon
  2479. :meth:`.Session.commit` or can be forced by using
  2480. :meth:`.Session.expire_all`. Accessing an expired
  2481. object whose row has been deleted will invoke a SELECT
  2482. to locate the row; when the row is not found, an
  2483. :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is
  2484. raised.
  2485. * The ``'fetch'`` strategy results in an additional
  2486. SELECT statement emitted and will significantly reduce
  2487. performance.
  2488. * The ``'evaluate'`` strategy performs a scan of
  2489. all matching objects within the :class:`.Session`; if the
  2490. contents of the :class:`.Session` are expired, such as
  2491. via a proceeding :meth:`.Session.commit` call, **this will
  2492. result in SELECT queries emitted for every matching object**.
  2493. * The :meth:`.MapperEvents.before_delete` and
  2494. :meth:`.MapperEvents.after_delete`
  2495. events **are not invoked** from this method. Instead, the
  2496. :meth:`.SessionEvents.after_bulk_delete` method is provided to
  2497. act upon a mass DELETE of entity rows.
  2498. .. seealso::
  2499. :meth:`.Query.update`
  2500. :ref:`inserts_and_updates` - Core SQL tutorial
  2501. """
  2502. delete_op = persistence.BulkDelete.factory(
  2503. self, synchronize_session)
  2504. delete_op.exec_()
  2505. return delete_op.rowcount
  2506. def update(self, values, synchronize_session='evaluate', update_args=None):
  2507. r"""Perform a bulk update query.
  2508. Updates rows matched by this query in the database.
  2509. E.g.::
  2510. sess.query(User).filter(User.age == 25).\
  2511. update({User.age: User.age - 10}, synchronize_session=False)
  2512. sess.query(User).filter(User.age == 25).\
  2513. update({"age": User.age - 10}, synchronize_session='evaluate')
  2514. .. warning:: The :meth:`.Query.update` method is a "bulk" operation,
  2515. which bypasses ORM unit-of-work automation in favor of greater
  2516. performance. **Please read all caveats and warnings below.**
  2517. :param values: a dictionary with attributes names, or alternatively
  2518. mapped attributes or SQL expressions, as keys, and literal
  2519. values or sql expressions as values. If :ref:`parameter-ordered
  2520. mode <updates_order_parameters>` is desired, the values can be
  2521. passed as a list of 2-tuples;
  2522. this requires that the :paramref:`~sqlalchemy.sql.expression.update.preserve_parameter_order`
  2523. flag is passed to the :paramref:`.Query.update.update_args` dictionary
  2524. as well.
  2525. .. versionchanged:: 1.0.0 - string names in the values dictionary
  2526. are now resolved against the mapped entity; previously, these
  2527. strings were passed as literal column names with no mapper-level
  2528. translation.
  2529. :param synchronize_session: chooses the strategy to update the
  2530. attributes on objects in the session. Valid values are:
  2531. ``False`` - don't synchronize the session. This option is the most
  2532. efficient and is reliable once the session is expired, which
  2533. typically occurs after a commit(), or explicitly using
  2534. expire_all(). Before the expiration, updated objects may still
  2535. remain in the session with stale values on their attributes, which
  2536. can lead to confusing results.
  2537. ``'fetch'`` - performs a select query before the update to find
  2538. objects that are matched by the update query. The updated
  2539. attributes are expired on matched objects.
  2540. ``'evaluate'`` - Evaluate the Query's criteria in Python straight
  2541. on the objects in the session. If evaluation of the criteria isn't
  2542. implemented, an exception is raised.
  2543. The expression evaluator currently doesn't account for differing
  2544. string collations between the database and Python.
  2545. :param update_args: Optional dictionary, if present will be passed
  2546. to the underlying :func:`.update` construct as the ``**kw`` for
  2547. the object. May be used to pass dialect-specific arguments such
  2548. as ``mysql_limit``, as well as other special arguments such as
  2549. :paramref:`~sqlalchemy.sql.expression.update.preserve_parameter_order`.
  2550. .. versionadded:: 1.0.0
  2551. :return: the count of rows matched as returned by the database's
  2552. "row count" feature.
  2553. .. warning:: **Additional Caveats for bulk query updates**
  2554. * The method does **not** offer in-Python cascading of
  2555. relationships - it is assumed that ON UPDATE CASCADE is
  2556. configured for any foreign key references which require
  2557. it, otherwise the database may emit an integrity
  2558. violation if foreign key references are being enforced.
  2559. After the UPDATE, dependent objects in the
  2560. :class:`.Session` which were impacted by an ON UPDATE
  2561. CASCADE may not contain the current state; this issue is
  2562. resolved once the :class:`.Session` is expired, which
  2563. normally occurs upon :meth:`.Session.commit` or can be
  2564. forced by using :meth:`.Session.expire_all`.
  2565. * The ``'fetch'`` strategy results in an additional
  2566. SELECT statement emitted and will significantly reduce
  2567. performance.
  2568. * The ``'evaluate'`` strategy performs a scan of
  2569. all matching objects within the :class:`.Session`; if the
  2570. contents of the :class:`.Session` are expired, such as
  2571. via a proceeding :meth:`.Session.commit` call, **this will
  2572. result in SELECT queries emitted for every matching object**.
  2573. * The method supports multiple table updates, as detailed
  2574. in :ref:`multi_table_updates`, and this behavior does
  2575. extend to support updates of joined-inheritance and
  2576. other multiple table mappings. However, the **join
  2577. condition of an inheritance mapper is not
  2578. automatically rendered**. Care must be taken in any
  2579. multiple-table update to explicitly include the joining
  2580. condition between those tables, even in mappings where
  2581. this is normally automatic. E.g. if a class ``Engineer``
  2582. subclasses ``Employee``, an UPDATE of the ``Engineer``
  2583. local table using criteria against the ``Employee``
  2584. local table might look like::
  2585. session.query(Engineer).\
  2586. filter(Engineer.id == Employee.id).\
  2587. filter(Employee.name == 'dilbert').\
  2588. update({"engineer_type": "programmer"})
  2589. * The polymorphic identity WHERE criteria is **not** included
  2590. for single- or
  2591. joined- table updates - this must be added **manually**, even
  2592. for single table inheritance.
  2593. * The :meth:`.MapperEvents.before_update` and
  2594. :meth:`.MapperEvents.after_update`
  2595. events **are not invoked from this method**. Instead, the
  2596. :meth:`.SessionEvents.after_bulk_update` method is provided to
  2597. act upon a mass UPDATE of entity rows.
  2598. .. seealso::
  2599. :meth:`.Query.delete`
  2600. :ref:`inserts_and_updates` - Core SQL tutorial
  2601. """
  2602. update_args = update_args or {}
  2603. update_op = persistence.BulkUpdate.factory(
  2604. self, synchronize_session, values, update_args)
  2605. update_op.exec_()
  2606. return update_op.rowcount
  2607. def _compile_context(self, labels=True):
  2608. if self.dispatch.before_compile:
  2609. for fn in self.dispatch.before_compile:
  2610. new_query = fn(self)
  2611. if new_query is not None:
  2612. self = new_query
  2613. context = QueryContext(self)
  2614. if context.statement is not None:
  2615. return context
  2616. context.labels = labels
  2617. context._for_update_arg = self._for_update_arg
  2618. for entity in self._entities:
  2619. entity.setup_context(self, context)
  2620. for rec in context.create_eager_joins:
  2621. strategy = rec[0]
  2622. strategy(*rec[1:])
  2623. if context.from_clause:
  2624. # "load from explicit FROMs" mode,
  2625. # i.e. when select_from() or join() is used
  2626. context.froms = list(context.from_clause)
  2627. # else "load from discrete FROMs" mode,
  2628. # i.e. when each _MappedEntity has its own FROM
  2629. if self._enable_single_crit:
  2630. self._adjust_for_single_inheritance(context)
  2631. if not context.primary_columns:
  2632. if self._only_load_props:
  2633. raise sa_exc.InvalidRequestError(
  2634. "No column-based properties specified for "
  2635. "refresh operation. Use session.expire() "
  2636. "to reload collections and related items.")
  2637. else:
  2638. raise sa_exc.InvalidRequestError(
  2639. "Query contains no columns with which to "
  2640. "SELECT from.")
  2641. if context.multi_row_eager_loaders and self._should_nest_selectable:
  2642. context.statement = self._compound_eager_statement(context)
  2643. else:
  2644. context.statement = self._simple_statement(context)
  2645. return context
  2646. def _compound_eager_statement(self, context):
  2647. # for eager joins present and LIMIT/OFFSET/DISTINCT,
  2648. # wrap the query inside a select,
  2649. # then append eager joins onto that
  2650. if context.order_by:
  2651. order_by_col_expr = \
  2652. sql_util.expand_column_list_from_order_by(
  2653. context.primary_columns,
  2654. context.order_by
  2655. )
  2656. else:
  2657. context.order_by = None
  2658. order_by_col_expr = []
  2659. inner = sql.select(
  2660. context.primary_columns + order_by_col_expr,
  2661. context.whereclause,
  2662. from_obj=context.froms,
  2663. use_labels=context.labels,
  2664. # TODO: this order_by is only needed if
  2665. # LIMIT/OFFSET is present in self._select_args,
  2666. # else the application on the outside is enough
  2667. order_by=context.order_by,
  2668. **self._select_args
  2669. )
  2670. for hint in self._with_hints:
  2671. inner = inner.with_hint(*hint)
  2672. if self._correlate:
  2673. inner = inner.correlate(*self._correlate)
  2674. inner = inner.alias()
  2675. equivs = self.__all_equivs()
  2676. context.adapter = sql_util.ColumnAdapter(inner, equivs)
  2677. statement = sql.select(
  2678. [inner] + context.secondary_columns,
  2679. use_labels=context.labels)
  2680. statement._for_update_arg = context._for_update_arg
  2681. from_clause = inner
  2682. for eager_join in context.eager_joins.values():
  2683. # EagerLoader places a 'stop_on' attribute on the join,
  2684. # giving us a marker as to where the "splice point" of
  2685. # the join should be
  2686. from_clause = sql_util.splice_joins(
  2687. from_clause,
  2688. eager_join, eager_join.stop_on)
  2689. statement.append_from(from_clause)
  2690. if context.order_by:
  2691. statement.append_order_by(
  2692. *context.adapter.copy_and_process(
  2693. context.order_by
  2694. )
  2695. )
  2696. statement.append_order_by(*context.eager_order_by)
  2697. return statement
  2698. def _simple_statement(self, context):
  2699. if not context.order_by:
  2700. context.order_by = None
  2701. if self._distinct is True and context.order_by:
  2702. context.primary_columns += \
  2703. sql_util.expand_column_list_from_order_by(
  2704. context.primary_columns,
  2705. context.order_by
  2706. )
  2707. context.froms += tuple(context.eager_joins.values())
  2708. statement = sql.select(
  2709. context.primary_columns +
  2710. context.secondary_columns,
  2711. context.whereclause,
  2712. from_obj=context.froms,
  2713. use_labels=context.labels,
  2714. order_by=context.order_by,
  2715. **self._select_args
  2716. )
  2717. statement._for_update_arg = context._for_update_arg
  2718. for hint in self._with_hints:
  2719. statement = statement.with_hint(*hint)
  2720. if self._correlate:
  2721. statement = statement.correlate(*self._correlate)
  2722. if context.eager_order_by:
  2723. statement.append_order_by(*context.eager_order_by)
  2724. return statement
  2725. def _adjust_for_single_inheritance(self, context):
  2726. """Apply single-table-inheritance filtering.
  2727. For all distinct single-table-inheritance mappers represented in
  2728. the columns clause of this query, add criterion to the WHERE
  2729. clause of the given QueryContext such that only the appropriate
  2730. subtypes are selected from the total results.
  2731. """
  2732. for (ext_info, adapter) in set(self._mapper_adapter_map.values()):
  2733. if ext_info in self._join_entities:
  2734. continue
  2735. single_crit = ext_info.mapper._single_table_criterion
  2736. if single_crit is not None:
  2737. if adapter:
  2738. single_crit = adapter.traverse(single_crit)
  2739. single_crit = self._adapt_clause(single_crit, False, False)
  2740. context.whereclause = sql.and_(
  2741. sql.True_._ifnone(context.whereclause),
  2742. single_crit)
  2743. from ..sql.selectable import ForUpdateArg
  2744. class LockmodeArg(ForUpdateArg):
  2745. @classmethod
  2746. def parse_legacy_query(self, mode):
  2747. if mode in (None, False):
  2748. return None
  2749. if mode == "read":
  2750. read = True
  2751. nowait = False
  2752. elif mode == "update":
  2753. read = nowait = False
  2754. elif mode == "update_nowait":
  2755. nowait = True
  2756. read = False
  2757. else:
  2758. raise sa_exc.ArgumentError(
  2759. "Unknown with_lockmode argument: %r" % mode)
  2760. return LockmodeArg(read=read, nowait=nowait)
  2761. class _QueryEntity(object):
  2762. """represent an entity column returned within a Query result."""
  2763. def __new__(cls, *args, **kwargs):
  2764. if cls is _QueryEntity:
  2765. entity = args[1]
  2766. if not isinstance(entity, util.string_types) and \
  2767. _is_mapped_class(entity):
  2768. cls = _MapperEntity
  2769. elif isinstance(entity, Bundle):
  2770. cls = _BundleEntity
  2771. else:
  2772. cls = _ColumnEntity
  2773. return object.__new__(cls)
  2774. def _clone(self):
  2775. q = self.__class__.__new__(self.__class__)
  2776. q.__dict__ = self.__dict__.copy()
  2777. return q
  2778. class _MapperEntity(_QueryEntity):
  2779. """mapper/class/AliasedClass entity"""
  2780. def __init__(self, query, entity):
  2781. if not query._primary_entity:
  2782. query._primary_entity = self
  2783. query._entities.append(self)
  2784. query._has_mapper_entities = True
  2785. self.entities = [entity]
  2786. self.expr = entity
  2787. supports_single_entity = True
  2788. use_id_for_hash = True
  2789. def setup_entity(self, ext_info, aliased_adapter):
  2790. self.mapper = ext_info.mapper
  2791. self.aliased_adapter = aliased_adapter
  2792. self.selectable = ext_info.selectable
  2793. self.is_aliased_class = ext_info.is_aliased_class
  2794. self._with_polymorphic = ext_info.with_polymorphic_mappers
  2795. self._polymorphic_discriminator = \
  2796. ext_info.polymorphic_on
  2797. self.entity_zero = ext_info
  2798. if ext_info.is_aliased_class:
  2799. self._label_name = self.entity_zero.name
  2800. else:
  2801. self._label_name = self.mapper.class_.__name__
  2802. self.path = self.entity_zero._path_registry
  2803. def set_with_polymorphic(self, query, cls_or_mappers,
  2804. selectable, polymorphic_on):
  2805. """Receive an update from a call to query.with_polymorphic().
  2806. Note the newer style of using a free standing with_polymporphic()
  2807. construct doesn't make use of this method.
  2808. """
  2809. if self.is_aliased_class:
  2810. # TODO: invalidrequest ?
  2811. raise NotImplementedError(
  2812. "Can't use with_polymorphic() against "
  2813. "an Aliased object"
  2814. )
  2815. if cls_or_mappers is None:
  2816. query._reset_polymorphic_adapter(self.mapper)
  2817. return
  2818. mappers, from_obj = self.mapper._with_polymorphic_args(
  2819. cls_or_mappers, selectable)
  2820. self._with_polymorphic = mappers
  2821. self._polymorphic_discriminator = polymorphic_on
  2822. self.selectable = from_obj
  2823. query._mapper_loads_polymorphically_with(
  2824. self.mapper, sql_util.ColumnAdapter(
  2825. from_obj, self.mapper._equivalent_columns))
  2826. @property
  2827. def type(self):
  2828. return self.mapper.class_
  2829. @property
  2830. def entity_zero_or_selectable(self):
  2831. return self.entity_zero
  2832. def corresponds_to(self, entity):
  2833. if entity.is_aliased_class:
  2834. if self.is_aliased_class:
  2835. if entity._base_alias is self.entity_zero._base_alias:
  2836. return True
  2837. return False
  2838. elif self.is_aliased_class:
  2839. if self.entity_zero._use_mapper_path:
  2840. return entity in self._with_polymorphic
  2841. else:
  2842. return entity is self.entity_zero
  2843. return entity.common_parent(self.entity_zero)
  2844. def adapt_to_selectable(self, query, sel):
  2845. query._entities.append(self)
  2846. def _get_entity_clauses(self, query, context):
  2847. adapter = None
  2848. if not self.is_aliased_class:
  2849. if query._polymorphic_adapters:
  2850. adapter = query._polymorphic_adapters.get(self.mapper, None)
  2851. else:
  2852. adapter = self.aliased_adapter
  2853. if adapter:
  2854. if query._from_obj_alias:
  2855. ret = adapter.wrap(query._from_obj_alias)
  2856. else:
  2857. ret = adapter
  2858. else:
  2859. ret = query._from_obj_alias
  2860. return ret
  2861. def row_processor(self, query, context, result):
  2862. adapter = self._get_entity_clauses(query, context)
  2863. if context.adapter and adapter:
  2864. adapter = adapter.wrap(context.adapter)
  2865. elif not adapter:
  2866. adapter = context.adapter
  2867. # polymorphic mappers which have concrete tables in
  2868. # their hierarchy usually
  2869. # require row aliasing unconditionally.
  2870. if not adapter and self.mapper._requires_row_aliasing:
  2871. adapter = sql_util.ColumnAdapter(
  2872. self.selectable,
  2873. self.mapper._equivalent_columns)
  2874. if query._primary_entity is self:
  2875. only_load_props = query._only_load_props
  2876. refresh_state = context.refresh_state
  2877. else:
  2878. only_load_props = refresh_state = None
  2879. _instance = loading._instance_processor(
  2880. self.mapper,
  2881. context,
  2882. result,
  2883. self.path,
  2884. adapter,
  2885. only_load_props=only_load_props,
  2886. refresh_state=refresh_state,
  2887. polymorphic_discriminator=self._polymorphic_discriminator
  2888. )
  2889. return _instance, self._label_name
  2890. def setup_context(self, query, context):
  2891. adapter = self._get_entity_clauses(query, context)
  2892. # if self._adapted_selectable is None:
  2893. context.froms += (self.selectable,)
  2894. if context.order_by is False and self.mapper.order_by:
  2895. context.order_by = self.mapper.order_by
  2896. # apply adaptation to the mapper's order_by if needed.
  2897. if adapter:
  2898. context.order_by = adapter.adapt_list(
  2899. util.to_list(
  2900. context.order_by
  2901. )
  2902. )
  2903. loading._setup_entity_query(
  2904. context, self.mapper, self,
  2905. self.path, adapter, context.primary_columns,
  2906. with_polymorphic=self._with_polymorphic,
  2907. only_load_props=query._only_load_props,
  2908. polymorphic_discriminator=self._polymorphic_discriminator)
  2909. def __str__(self):
  2910. return str(self.mapper)
  2911. @inspection._self_inspects
  2912. class Bundle(InspectionAttr):
  2913. """A grouping of SQL expressions that are returned by a :class:`.Query`
  2914. under one namespace.
  2915. The :class:`.Bundle` essentially allows nesting of the tuple-based
  2916. results returned by a column-oriented :class:`.Query` object. It also
  2917. is extensible via simple subclassing, where the primary capability
  2918. to override is that of how the set of expressions should be returned,
  2919. allowing post-processing as well as custom return types, without
  2920. involving ORM identity-mapped classes.
  2921. .. versionadded:: 0.9.0
  2922. .. seealso::
  2923. :ref:`bundles`
  2924. """
  2925. single_entity = False
  2926. """If True, queries for a single Bundle will be returned as a single
  2927. entity, rather than an element within a keyed tuple."""
  2928. is_clause_element = False
  2929. is_mapper = False
  2930. is_aliased_class = False
  2931. def __init__(self, name, *exprs, **kw):
  2932. r"""Construct a new :class:`.Bundle`.
  2933. e.g.::
  2934. bn = Bundle("mybundle", MyClass.x, MyClass.y)
  2935. for row in session.query(bn).filter(
  2936. bn.c.x == 5).filter(bn.c.y == 4):
  2937. print(row.mybundle.x, row.mybundle.y)
  2938. :param name: name of the bundle.
  2939. :param \*exprs: columns or SQL expressions comprising the bundle.
  2940. :param single_entity=False: if True, rows for this :class:`.Bundle`
  2941. can be returned as a "single entity" outside of any enclosing tuple
  2942. in the same manner as a mapped entity.
  2943. """
  2944. self.name = self._label = name
  2945. self.exprs = exprs
  2946. self.c = self.columns = ColumnCollection()
  2947. self.columns.update((getattr(col, "key", col._label), col)
  2948. for col in exprs)
  2949. self.single_entity = kw.pop('single_entity', self.single_entity)
  2950. columns = None
  2951. """A namespace of SQL expressions referred to by this :class:`.Bundle`.
  2952. e.g.::
  2953. bn = Bundle("mybundle", MyClass.x, MyClass.y)
  2954. q = sess.query(bn).filter(bn.c.x == 5)
  2955. Nesting of bundles is also supported::
  2956. b1 = Bundle("b1",
  2957. Bundle('b2', MyClass.a, MyClass.b),
  2958. Bundle('b3', MyClass.x, MyClass.y)
  2959. )
  2960. q = sess.query(b1).filter(
  2961. b1.c.b2.c.a == 5).filter(b1.c.b3.c.y == 9)
  2962. .. seealso::
  2963. :attr:`.Bundle.c`
  2964. """
  2965. c = None
  2966. """An alias for :attr:`.Bundle.columns`."""
  2967. def _clone(self):
  2968. cloned = self.__class__.__new__(self.__class__)
  2969. cloned.__dict__.update(self.__dict__)
  2970. return cloned
  2971. def __clause_element__(self):
  2972. return expression.ClauseList(group=False, *self.c)
  2973. @property
  2974. def clauses(self):
  2975. return self.__clause_element__().clauses
  2976. def label(self, name):
  2977. """Provide a copy of this :class:`.Bundle` passing a new label."""
  2978. cloned = self._clone()
  2979. cloned.name = name
  2980. return cloned
  2981. def create_row_processor(self, query, procs, labels):
  2982. """Produce the "row processing" function for this :class:`.Bundle`.
  2983. May be overridden by subclasses.
  2984. .. seealso::
  2985. :ref:`bundles` - includes an example of subclassing.
  2986. """
  2987. keyed_tuple = util.lightweight_named_tuple('result', labels)
  2988. def proc(row):
  2989. return keyed_tuple([proc(row) for proc in procs])
  2990. return proc
  2991. class _BundleEntity(_QueryEntity):
  2992. use_id_for_hash = False
  2993. def __init__(self, query, bundle, setup_entities=True):
  2994. query._entities.append(self)
  2995. self.bundle = self.expr = bundle
  2996. self.type = type(bundle)
  2997. self._label_name = bundle.name
  2998. self._entities = []
  2999. if setup_entities:
  3000. for expr in bundle.exprs:
  3001. if isinstance(expr, Bundle):
  3002. _BundleEntity(self, expr)
  3003. else:
  3004. _ColumnEntity(self, expr, namespace=self)
  3005. self.supports_single_entity = self.bundle.single_entity
  3006. @property
  3007. def entities(self):
  3008. entities = []
  3009. for ent in self._entities:
  3010. entities.extend(ent.entities)
  3011. return entities
  3012. @property
  3013. def entity_zero(self):
  3014. for ent in self._entities:
  3015. ezero = ent.entity_zero
  3016. if ezero is not None:
  3017. return ezero
  3018. else:
  3019. return None
  3020. def corresponds_to(self, entity):
  3021. # TODO: this seems to have no effect for
  3022. # _ColumnEntity either
  3023. return False
  3024. @property
  3025. def entity_zero_or_selectable(self):
  3026. for ent in self._entities:
  3027. ezero = ent.entity_zero_or_selectable
  3028. if ezero is not None:
  3029. return ezero
  3030. else:
  3031. return None
  3032. def adapt_to_selectable(self, query, sel):
  3033. c = _BundleEntity(query, self.bundle, setup_entities=False)
  3034. # c._label_name = self._label_name
  3035. # c.entity_zero = self.entity_zero
  3036. # c.entities = self.entities
  3037. for ent in self._entities:
  3038. ent.adapt_to_selectable(c, sel)
  3039. def setup_entity(self, ext_info, aliased_adapter):
  3040. for ent in self._entities:
  3041. ent.setup_entity(ext_info, aliased_adapter)
  3042. def setup_context(self, query, context):
  3043. for ent in self._entities:
  3044. ent.setup_context(query, context)
  3045. def row_processor(self, query, context, result):
  3046. procs, labels = zip(
  3047. *[ent.row_processor(query, context, result)
  3048. for ent in self._entities]
  3049. )
  3050. proc = self.bundle.create_row_processor(query, procs, labels)
  3051. return proc, self._label_name
  3052. class _ColumnEntity(_QueryEntity):
  3053. """Column/expression based entity."""
  3054. def __init__(self, query, column, namespace=None):
  3055. self.expr = column
  3056. self.namespace = namespace
  3057. search_entities = True
  3058. check_column = False
  3059. if isinstance(column, util.string_types):
  3060. column = sql.literal_column(column)
  3061. self._label_name = column.name
  3062. search_entities = False
  3063. check_column = True
  3064. _entity = None
  3065. elif isinstance(column, (
  3066. attributes.QueryableAttribute,
  3067. interfaces.PropComparator
  3068. )):
  3069. _entity = getattr(column, '_parententity', None)
  3070. if _entity is not None:
  3071. search_entities = False
  3072. self._label_name = column.key
  3073. column = column._query_clause_element()
  3074. check_column = True
  3075. if isinstance(column, Bundle):
  3076. _BundleEntity(query, column)
  3077. return
  3078. if not isinstance(column, sql.ColumnElement):
  3079. if hasattr(column, '_select_iterable'):
  3080. # break out an object like Table into
  3081. # individual columns
  3082. for c in column._select_iterable:
  3083. if c is column:
  3084. break
  3085. _ColumnEntity(query, c, namespace=column)
  3086. else:
  3087. return
  3088. raise sa_exc.InvalidRequestError(
  3089. "SQL expression, column, or mapped entity "
  3090. "expected - got '%r'" % (column, )
  3091. )
  3092. elif not check_column:
  3093. self._label_name = getattr(column, 'key', None)
  3094. search_entities = True
  3095. self.type = type_ = column.type
  3096. self.use_id_for_hash = not type_.hashable
  3097. # If the Column is unnamed, give it a
  3098. # label() so that mutable column expressions
  3099. # can be located in the result even
  3100. # if the expression's identity has been changed
  3101. # due to adaption.
  3102. if not column._label and not getattr(column, 'is_literal', False):
  3103. column = column.label(self._label_name)
  3104. query._entities.append(self)
  3105. self.column = column
  3106. self.froms = set()
  3107. # look for ORM entities represented within the
  3108. # given expression. Try to count only entities
  3109. # for columns whose FROM object is in the actual list
  3110. # of FROMs for the overall expression - this helps
  3111. # subqueries which were built from ORM constructs from
  3112. # leaking out their entities into the main select construct
  3113. self.actual_froms = actual_froms = set(column._from_objects)
  3114. if not search_entities:
  3115. self.entity_zero = _entity
  3116. if _entity:
  3117. self.entities = [_entity]
  3118. self.mapper = _entity.mapper
  3119. else:
  3120. self.entities = []
  3121. self.mapper = None
  3122. self._from_entities = set(self.entities)
  3123. else:
  3124. all_elements = [
  3125. elem for elem in sql_util.surface_column_elements(column)
  3126. if 'parententity' in elem._annotations
  3127. ]
  3128. self.entities = util.unique_list([
  3129. elem._annotations['parententity']
  3130. for elem in all_elements
  3131. if 'parententity' in elem._annotations
  3132. ])
  3133. self._from_entities = set([
  3134. elem._annotations['parententity']
  3135. for elem in all_elements
  3136. if 'parententity' in elem._annotations
  3137. and actual_froms.intersection(elem._from_objects)
  3138. ])
  3139. if self.entities:
  3140. self.entity_zero = self.entities[0]
  3141. self.mapper = self.entity_zero.mapper
  3142. elif self.namespace is not None:
  3143. self.entity_zero = self.namespace
  3144. self.mapper = None
  3145. else:
  3146. self.entity_zero = None
  3147. self.mapper = None
  3148. supports_single_entity = False
  3149. @property
  3150. def entity_zero_or_selectable(self):
  3151. if self.entity_zero is not None:
  3152. return self.entity_zero
  3153. elif self.actual_froms:
  3154. return list(self.actual_froms)[0]
  3155. else:
  3156. return None
  3157. def adapt_to_selectable(self, query, sel):
  3158. c = _ColumnEntity(query, sel.corresponding_column(self.column))
  3159. c._label_name = self._label_name
  3160. c.entity_zero = self.entity_zero
  3161. c.entities = self.entities
  3162. def setup_entity(self, ext_info, aliased_adapter):
  3163. if 'selectable' not in self.__dict__:
  3164. self.selectable = ext_info.selectable
  3165. if self.actual_froms.intersection(ext_info.selectable._from_objects):
  3166. self.froms.add(ext_info.selectable)
  3167. def corresponds_to(self, entity):
  3168. # TODO: just returning False here,
  3169. # no tests fail
  3170. if self.entity_zero is None:
  3171. return False
  3172. elif _is_aliased_class(entity):
  3173. # TODO: polymorphic subclasses ?
  3174. return entity is self.entity_zero
  3175. else:
  3176. return not _is_aliased_class(self.entity_zero) and \
  3177. entity.common_parent(self.entity_zero)
  3178. def row_processor(self, query, context, result):
  3179. if ('fetch_column', self) in context.attributes:
  3180. column = context.attributes[('fetch_column', self)]
  3181. else:
  3182. column = query._adapt_clause(self.column, False, True)
  3183. if context.adapter:
  3184. column = context.adapter.columns[column]
  3185. getter = result._getter(column)
  3186. return getter, self._label_name
  3187. def setup_context(self, query, context):
  3188. column = query._adapt_clause(self.column, False, True)
  3189. context.froms += tuple(self.froms)
  3190. context.primary_columns.append(column)
  3191. context.attributes[('fetch_column', self)] = column
  3192. def __str__(self):
  3193. return str(self.column)
  3194. class QueryContext(object):
  3195. __slots__ = (
  3196. 'multi_row_eager_loaders', 'adapter', 'froms', 'for_update',
  3197. 'query', 'session', 'autoflush', 'populate_existing',
  3198. 'invoke_all_eagers', 'version_check', 'refresh_state',
  3199. 'primary_columns', 'secondary_columns', 'eager_order_by',
  3200. 'eager_joins', 'create_eager_joins', 'propagate_options',
  3201. 'attributes', 'statement', 'from_clause', 'whereclause',
  3202. 'order_by', 'labels', '_for_update_arg', 'runid', 'partials'
  3203. )
  3204. def __init__(self, query):
  3205. if query._statement is not None:
  3206. if isinstance(query._statement, expression.SelectBase) and \
  3207. not query._statement._textual and \
  3208. not query._statement.use_labels:
  3209. self.statement = query._statement.apply_labels()
  3210. else:
  3211. self.statement = query._statement
  3212. else:
  3213. self.statement = None
  3214. self.from_clause = query._from_obj
  3215. self.whereclause = query._criterion
  3216. self.order_by = query._order_by
  3217. self.multi_row_eager_loaders = False
  3218. self.adapter = None
  3219. self.froms = ()
  3220. self.for_update = None
  3221. self.query = query
  3222. self.session = query.session
  3223. self.autoflush = query._autoflush
  3224. self.populate_existing = query._populate_existing
  3225. self.invoke_all_eagers = query._invoke_all_eagers
  3226. self.version_check = query._version_check
  3227. self.refresh_state = query._refresh_state
  3228. self.primary_columns = []
  3229. self.secondary_columns = []
  3230. self.eager_order_by = []
  3231. self.eager_joins = {}
  3232. self.create_eager_joins = []
  3233. self.propagate_options = set(o for o in query._with_options if
  3234. o.propagate_to_loaders)
  3235. self.attributes = query._attributes.copy()
  3236. class AliasOption(interfaces.MapperOption):
  3237. def __init__(self, alias):
  3238. r"""Return a :class:`.MapperOption` that will indicate to the :class:`.Query`
  3239. that the main table has been aliased.
  3240. This is a seldom-used option to suit the
  3241. very rare case that :func:`.contains_eager`
  3242. is being used in conjunction with a user-defined SELECT
  3243. statement that aliases the parent table. E.g.::
  3244. # define an aliased UNION called 'ulist'
  3245. ulist = users.select(users.c.user_id==7).\
  3246. union(users.select(users.c.user_id>7)).\
  3247. alias('ulist')
  3248. # add on an eager load of "addresses"
  3249. statement = ulist.outerjoin(addresses).\
  3250. select().apply_labels()
  3251. # create query, indicating "ulist" will be an
  3252. # alias for the main table, "addresses"
  3253. # property should be eager loaded
  3254. query = session.query(User).options(
  3255. contains_alias(ulist),
  3256. contains_eager(User.addresses))
  3257. # then get results via the statement
  3258. results = query.from_statement(statement).all()
  3259. :param alias: is the string name of an alias, or a
  3260. :class:`~.sql.expression.Alias` object representing
  3261. the alias.
  3262. """
  3263. self.alias = alias
  3264. def process_query(self, query):
  3265. if isinstance(self.alias, util.string_types):
  3266. alias = query._mapper_zero().mapped_table.alias(self.alias)
  3267. else:
  3268. alias = self.alias
  3269. query._from_obj_alias = sql_util.ColumnAdapter(alias)