You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3429 lines
119KB

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