1# sql/selectable.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
8"""The :class:`_expression.FromClause` class of SQL expression elements,
9representing
10SQL tables and derived rowsets.
11
12"""
13
14import collections
15import itertools
16import operator
17from operator import attrgetter
18
19from sqlalchemy.sql.visitors import Visitable
20from . import operators
21from . import type_api
22from .annotation import Annotated
23from .base import _from_objects
24from .base import _generative
25from .base import ColumnCollection
26from .base import ColumnSet
27from .base import Executable
28from .base import Generative
29from .base import Immutable
30from .elements import _anonymous_label
31from .elements import _clause_element_as_expr
32from .elements import _clone
33from .elements import _cloned_difference
34from .elements import _cloned_intersection
35from .elements import _document_text_coercion
36from .elements import _expand_cloned
37from .elements import _interpret_as_column_or_from
38from .elements import _literal_and_labels_as_label_reference
39from .elements import _literal_as_label_reference
40from .elements import _literal_as_text
41from .elements import _no_text_coercion
42from .elements import _select_iterables
43from .elements import and_
44from .elements import BindParameter
45from .elements import ClauseElement
46from .elements import ClauseList
47from .elements import Grouping
48from .elements import literal_column
49from .elements import True_
50from .elements import UnaryExpression
51from .. import exc
52from .. import inspection
53from .. import util
54
55
56def _interpret_as_from(element):
57 insp = inspection.inspect(element, raiseerr=False)
58 if insp is None:
59 if isinstance(element, util.string_types):
60 _no_text_coercion(element)
61 try:
62 return insp.selectable
63 except AttributeError as err:
64 util.raise_(
65 exc.ArgumentError("FROM expression expected"), replace_context=err
66 )
67
68
69def _interpret_as_select(element):
70 element = _interpret_as_from(element)
71 if isinstance(element, Alias):
72 element = element.original
73 if not isinstance(element, SelectBase):
74 element = element.select()
75 return element
76
77
78class _OffsetLimitParam(BindParameter):
79 @property
80 def _limit_offset_value(self):
81 return self.effective_value
82
83
84def _offset_or_limit_clause(element, name=None, type_=None):
85 """Convert the given value to an "offset or limit" clause.
86
87 This handles incoming integers and converts to an expression; if
88 an expression is already given, it is passed through.
89
90 """
91 if element is None:
92 return None
93 elif hasattr(element, "__clause_element__"):
94 return element.__clause_element__()
95 elif isinstance(element, Visitable):
96 return element
97 else:
98 value = util.asint(element)
99 return _OffsetLimitParam(name, value, type_=type_, unique=True)
100
101
102def _offset_or_limit_clause_asint(clause, attrname):
103 """Convert the "offset or limit" clause of a select construct to an
104 integer.
105
106 This is only possible if the value is stored as a simple bound parameter.
107 Otherwise, a compilation error is raised.
108
109 """
110 if clause is None:
111 return None
112 try:
113 value = clause._limit_offset_value
114 except AttributeError as err:
115 util.raise_(
116 exc.CompileError(
117 "This SELECT structure does not use a simple "
118 "integer value for %s" % attrname
119 ),
120 replace_context=err,
121 )
122 else:
123 return util.asint(value)
124
125
126def subquery(alias, *args, **kwargs):
127 r"""Return an :class:`_expression.Alias` object derived
128 from a :class:`_expression.Select`.
129
130 :param alias: the alias name
131
132 :param \*args, \**kwargs: all other arguments are delivered to the
133 :func:`_expression.select` function.
134
135 """
136 return Select(*args, **kwargs).alias(alias)
137
138
139class Selectable(ClauseElement):
140 """Mark a class as being selectable."""
141
142 __visit_name__ = "selectable"
143
144 is_selectable = True
145
146 @property
147 def selectable(self):
148 return self
149
150
151class HasPrefixes(object):
152 _prefixes = ()
153
154 @_generative
155 @_document_text_coercion(
156 "expr",
157 ":meth:`_expression.HasPrefixes.prefix_with`",
158 ":paramref:`.HasPrefixes.prefix_with.*expr`",
159 )
160 def prefix_with(self, *expr, **kw):
161 r"""Add one or more expressions following the statement keyword, i.e.
162 SELECT, INSERT, UPDATE, or DELETE. Generative.
163
164 This is used to support backend-specific prefix keywords such as those
165 provided by MySQL.
166
167 E.g.::
168
169 stmt = table.insert().prefix_with("LOW_PRIORITY", dialect="mysql")
170
171 # MySQL 5.7 optimizer hints
172 stmt = select([table]).prefix_with(
173 "/*+ BKA(t1) */", dialect="mysql")
174
175 Multiple prefixes can be specified by multiple calls
176 to :meth:`_expression.HasPrefixes.prefix_with`.
177
178 :param \*expr: textual or :class:`_expression.ClauseElement`
179 construct which
180 will be rendered following the INSERT, UPDATE, or DELETE
181 keyword.
182 :param \**kw: A single keyword 'dialect' is accepted. This is an
183 optional string dialect name which will
184 limit rendering of this prefix to only that dialect.
185
186 """
187 dialect = kw.pop("dialect", None)
188 if kw:
189 raise exc.ArgumentError(
190 "Unsupported argument(s): %s" % ",".join(kw)
191 )
192 self._setup_prefixes(expr, dialect)
193
194 def _setup_prefixes(self, prefixes, dialect=None):
195 self._prefixes = self._prefixes + tuple(
196 [
197 (_literal_as_text(p, allow_coercion_to_text=True), dialect)
198 for p in prefixes
199 ]
200 )
201
202
203class HasSuffixes(object):
204 _suffixes = ()
205
206 @_generative
207 @_document_text_coercion(
208 "expr",
209 ":meth:`_expression.HasSuffixes.suffix_with`",
210 ":paramref:`.HasSuffixes.suffix_with.*expr`",
211 )
212 def suffix_with(self, *expr, **kw):
213 r"""Add one or more expressions following the statement as a whole.
214
215 This is used to support backend-specific suffix keywords on
216 certain constructs.
217
218 E.g.::
219
220 stmt = select([col1, col2]).cte().suffix_with(
221 "cycle empno set y_cycle to 1 default 0", dialect="oracle")
222
223 Multiple suffixes can be specified by multiple calls
224 to :meth:`_expression.HasSuffixes.suffix_with`.
225
226 :param \*expr: textual or :class:`_expression.ClauseElement`
227 construct which
228 will be rendered following the target clause.
229 :param \**kw: A single keyword 'dialect' is accepted. This is an
230 optional string dialect name which will
231 limit rendering of this suffix to only that dialect.
232
233 """
234 dialect = kw.pop("dialect", None)
235 if kw:
236 raise exc.ArgumentError(
237 "Unsupported argument(s): %s" % ",".join(kw)
238 )
239 self._setup_suffixes(expr, dialect)
240
241 def _setup_suffixes(self, suffixes, dialect=None):
242 self._suffixes = self._suffixes + tuple(
243 [
244 (_literal_as_text(p, allow_coercion_to_text=True), dialect)
245 for p in suffixes
246 ]
247 )
248
249
250class FromClause(Selectable):
251 """Represent an element that can be used within the ``FROM``
252 clause of a ``SELECT`` statement.
253
254 The most common forms of :class:`_expression.FromClause` are the
255 :class:`_schema.Table` and the :func:`_expression.select` constructs. Key
256 features common to all :class:`_expression.FromClause` objects include:
257
258 * a :attr:`.c` collection, which provides per-name access to a collection
259 of :class:`_expression.ColumnElement` objects.
260 * a :attr:`.primary_key` attribute, which is a collection of all those
261 :class:`_expression.ColumnElement`
262 objects that indicate the ``primary_key`` flag.
263 * Methods to generate various derivations of a "from" clause, including
264 :meth:`_expression.FromClause.alias`,
265 :meth:`_expression.FromClause.join`,
266 :meth:`_expression.FromClause.select`.
267
268
269 """
270
271 __visit_name__ = "fromclause"
272 named_with_column = False
273 _hide_froms = []
274
275 _is_join = False
276 _is_select = False
277 _is_from_container = False
278
279 _is_lateral = False
280
281 _textual = False
282 """A marker that allows us to easily distinguish a :class:`.TextAsFrom`
283 or similar object from other kinds of :class:`_expression.FromClause`
284 objects."""
285
286 schema = None
287 """Define the 'schema' attribute for this :class:`_expression.FromClause`.
288
289 This is typically ``None`` for most objects except that of
290 :class:`_schema.Table`, where it is taken as the value of the
291 :paramref:`_schema.Table.schema` argument.
292
293 """
294
295 def _translate_schema(self, effective_schema, map_):
296 return effective_schema
297
298 _memoized_property = util.group_expirable_memoized_property(["_columns"])
299
300 @util.deprecated(
301 "1.1",
302 message="The :meth:`.FromClause.count` method is deprecated, "
303 "and will be removed in a future release. Please use the "
304 ":class:`_functions.count` function available from the "
305 ":attr:`.func` namespace.",
306 )
307 @util.dependencies("sqlalchemy.sql.functions")
308 def count(self, functions, whereclause=None, **params):
309 """Return a SELECT COUNT generated against this
310 :class:`_expression.FromClause`.
311
312 .. seealso::
313
314 :class:`_functions.count`
315
316 """
317
318 if self.primary_key:
319 col = list(self.primary_key)[0]
320 else:
321 col = list(self.columns)[0]
322 return Select(
323 [functions.func.count(col).label("tbl_row_count")],
324 whereclause,
325 from_obj=[self],
326 **params
327 )
328
329 def select(self, whereclause=None, **params):
330 """Return a SELECT of this :class:`_expression.FromClause`.
331
332 .. seealso::
333
334 :func:`_expression.select` - general purpose
335 method which allows for arbitrary column lists.
336
337 """
338
339 return Select([self], whereclause, **params)
340
341 def join(self, right, onclause=None, isouter=False, full=False):
342 """Return a :class:`_expression.Join` from this
343 :class:`_expression.FromClause` to another
344 :class:`_expression.FromClause`.
345
346 E.g.::
347
348 from sqlalchemy import join
349
350 j = user_table.join(address_table,
351 user_table.c.id == address_table.c.user_id)
352 stmt = select([user_table]).select_from(j)
353
354 would emit SQL along the lines of::
355
356 SELECT user.id, user.name FROM user
357 JOIN address ON user.id = address.user_id
358
359 :param right: the right side of the join; this is any
360 :class:`_expression.FromClause` object such as a
361 :class:`_schema.Table` object, and
362 may also be a selectable-compatible object such as an ORM-mapped
363 class.
364
365 :param onclause: a SQL expression representing the ON clause of the
366 join. If left at ``None``, :meth:`_expression.FromClause.join`
367 will attempt to
368 join the two tables based on a foreign key relationship.
369
370 :param isouter: if True, render a LEFT OUTER JOIN, instead of JOIN.
371
372 :param full: if True, render a FULL OUTER JOIN, instead of LEFT OUTER
373 JOIN. Implies :paramref:`.FromClause.join.isouter`.
374
375 .. versionadded:: 1.1
376
377 .. seealso::
378
379 :func:`_expression.join` - standalone function
380
381 :class:`_expression.Join` - the type of object produced
382
383 """
384
385 return Join(self, right, onclause, isouter, full)
386
387 def outerjoin(self, right, onclause=None, full=False):
388 """Return a :class:`_expression.Join` from this
389 :class:`_expression.FromClause`
390 to another :class:`FromClause`, with the "isouter" flag set to
391 True.
392
393 E.g.::
394
395 from sqlalchemy import outerjoin
396
397 j = user_table.outerjoin(address_table,
398 user_table.c.id == address_table.c.user_id)
399
400 The above is equivalent to::
401
402 j = user_table.join(
403 address_table,
404 user_table.c.id == address_table.c.user_id,
405 isouter=True)
406
407 :param right: the right side of the join; this is any
408 :class:`_expression.FromClause` object such as a
409 :class:`_schema.Table` object, and
410 may also be a selectable-compatible object such as an ORM-mapped
411 class.
412
413 :param onclause: a SQL expression representing the ON clause of the
414 join. If left at ``None``, :meth:`_expression.FromClause.join`
415 will attempt to
416 join the two tables based on a foreign key relationship.
417
418 :param full: if True, render a FULL OUTER JOIN, instead of
419 LEFT OUTER JOIN.
420
421 .. versionadded:: 1.1
422
423 .. seealso::
424
425 :meth:`_expression.FromClause.join`
426
427 :class:`_expression.Join`
428
429 """
430
431 return Join(self, right, onclause, True, full)
432
433 def alias(self, name=None, flat=False):
434 """Return an alias of this :class:`_expression.FromClause`.
435
436 E.g.::
437
438 a2 = some_table.alias('a2')
439
440 The above code creates an :class:`_expression.Alias`
441 object which can be used
442 as a FROM clause in any SELECT statement.
443
444 .. seealso::
445
446 :ref:`core_tutorial_aliases`
447
448 :func:`_expression.alias`
449
450 """
451
452 return Alias._construct(self, name)
453
454 def lateral(self, name=None):
455 """Return a LATERAL alias of this :class:`_expression.FromClause`.
456
457 The return value is the :class:`_expression.Lateral` construct also
458 provided by the top-level :func:`_expression.lateral` function.
459
460 .. versionadded:: 1.1
461
462 .. seealso::
463
464 :ref:`lateral_selects` - overview of usage.
465
466 """
467 return Lateral._construct(self, name)
468
469 def tablesample(self, sampling, name=None, seed=None):
470 """Return a TABLESAMPLE alias of this :class:`_expression.FromClause`.
471
472 The return value is the :class:`_expression.TableSample`
473 construct also
474 provided by the top-level :func:`_expression.tablesample` function.
475
476 .. versionadded:: 1.1
477
478 .. seealso::
479
480 :func:`_expression.tablesample` - usage guidelines and parameters
481
482 """
483 return TableSample._construct(self, sampling, name, seed)
484
485 def is_derived_from(self, fromclause):
486 """Return ``True`` if this :class:`_expression.FromClause` is
487 'derived' from the given ``FromClause``.
488
489 An example would be an Alias of a Table is derived from that Table.
490
491 """
492 # this is essentially an "identity" check in the base class.
493 # Other constructs override this to traverse through
494 # contained elements.
495 return fromclause in self._cloned_set
496
497 def _is_lexical_equivalent(self, other):
498 """Return ``True`` if this :class:`_expression.FromClause` and
499 the other represent the same lexical identity.
500
501 This tests if either one is a copy of the other, or
502 if they are the same via annotation identity.
503
504 """
505 return self._cloned_set.intersection(other._cloned_set)
506
507 @util.dependencies("sqlalchemy.sql.util")
508 def replace_selectable(self, sqlutil, old, alias):
509 """Replace all occurrences of FromClause 'old' with the given Alias
510 object, returning a copy of this :class:`_expression.FromClause`.
511
512 """
513
514 return sqlutil.ClauseAdapter(alias).traverse(self)
515
516 def correspond_on_equivalents(self, column, equivalents):
517 """Return corresponding_column for the given column, or if None
518 search for a match in the given dictionary.
519
520 """
521 col = self.corresponding_column(column, require_embedded=True)
522 if col is None and col in equivalents:
523 for equiv in equivalents[col]:
524 nc = self.corresponding_column(equiv, require_embedded=True)
525 if nc:
526 return nc
527 return col
528
529 def corresponding_column(self, column, require_embedded=False):
530 """Given a :class:`_expression.ColumnElement`, return the exported
531 :class:`_expression.ColumnElement` object from this
532 :class:`expression.Selectable`
533 which corresponds to that original
534 :class:`~sqlalchemy.schema.Column` via a common ancestor
535 column.
536
537 :param column: the target :class:`_expression.ColumnElement`
538 to be matched
539
540 :param require_embedded: only return corresponding columns for
541 the given :class:`_expression.ColumnElement`, if the given
542 :class:`_expression.ColumnElement`
543 is actually present within a sub-element
544 of this :class:`_expression.FromClause`.
545 Normally the column will match if
546 it merely shares a common ancestor with one of the exported
547 columns of this :class:`_expression.FromClause`.
548
549 """
550
551 def embedded(expanded_proxy_set, target_set):
552 for t in target_set.difference(expanded_proxy_set):
553 if not set(_expand_cloned([t])).intersection(
554 expanded_proxy_set
555 ):
556 return False
557 return True
558
559 # don't dig around if the column is locally present
560 if self.c.contains_column(column):
561 return column
562 col, intersect = None, None
563 target_set = column.proxy_set
564 cols = self.c._all_columns
565 for c in cols:
566 expanded_proxy_set = set(_expand_cloned(c.proxy_set))
567 i = target_set.intersection(expanded_proxy_set)
568 if i and (
569 not require_embedded
570 or embedded(expanded_proxy_set, target_set)
571 ):
572 if col is None:
573
574 # no corresponding column yet, pick this one.
575
576 col, intersect = c, i
577 elif len(i) > len(intersect):
578
579 # 'c' has a larger field of correspondence than
580 # 'col'. i.e. selectable.c.a1_x->a1.c.x->table.c.x
581 # matches a1.c.x->table.c.x better than
582 # selectable.c.x->table.c.x does.
583
584 col, intersect = c, i
585 elif i == intersect:
586
587 # they have the same field of correspondence. see
588 # which proxy_set has fewer columns in it, which
589 # indicates a closer relationship with the root
590 # column. Also take into account the "weight"
591 # attribute which CompoundSelect() uses to give
592 # higher precedence to columns based on vertical
593 # position in the compound statement, and discard
594 # columns that have no reference to the target
595 # column (also occurs with CompoundSelect)
596
597 col_distance = util.reduce(
598 operator.add,
599 [
600 sc._annotations.get("weight", 1)
601 for sc in col._uncached_proxy_set()
602 if sc.shares_lineage(column)
603 ],
604 )
605 c_distance = util.reduce(
606 operator.add,
607 [
608 sc._annotations.get("weight", 1)
609 for sc in c._uncached_proxy_set()
610 if sc.shares_lineage(column)
611 ],
612 )
613 if c_distance < col_distance:
614 col, intersect = c, i
615 return col
616
617 @property
618 def description(self):
619 """A brief description of this :class:`_expression.FromClause`.
620
621 Used primarily for error message formatting.
622
623 """
624 return getattr(self, "name", self.__class__.__name__ + " object")
625
626 def _reset_exported(self):
627 """Delete memoized collections when a FromClause is cloned."""
628
629 self._memoized_property.expire_instance(self)
630
631 @_memoized_property
632 def columns(self):
633 """A named-based collection of :class:`_expression.ColumnElement`
634 objects
635 maintained by this :class:`_expression.FromClause`.
636
637 The :attr:`.columns`, or :attr:`.c` collection, is the gateway
638 to the construction of SQL expressions using table-bound or
639 other selectable-bound columns::
640
641 select([mytable]).where(mytable.c.somecolumn == 5)
642
643 """
644
645 if "_columns" not in self.__dict__:
646 self._init_collections()
647 self._populate_column_collection()
648 return self._columns.as_immutable()
649
650 @_memoized_property
651 def primary_key(self):
652 """Return the collection of :class:`_schema.Column` objects
653 which comprise the primary key of this FromClause.
654
655 """
656 self._init_collections()
657 self._populate_column_collection()
658 return self.primary_key
659
660 @_memoized_property
661 def foreign_keys(self):
662 """Return the collection of :class:`_schema.ForeignKey` objects
663 which this FromClause references.
664
665 """
666 self._init_collections()
667 self._populate_column_collection()
668 return self.foreign_keys
669
670 c = property(
671 attrgetter("columns"),
672 doc="An alias for the :attr:`.columns` attribute.",
673 )
674 _select_iterable = property(attrgetter("columns"))
675
676 def _init_collections(self):
677 assert "_columns" not in self.__dict__
678 assert "primary_key" not in self.__dict__
679 assert "foreign_keys" not in self.__dict__
680
681 self._columns = ColumnCollection()
682 self.primary_key = ColumnSet()
683 self.foreign_keys = set()
684
685 @property
686 def _cols_populated(self):
687 return "_columns" in self.__dict__
688
689 def _populate_column_collection(self):
690 """Called on subclasses to establish the .c collection.
691
692 Each implementation has a different way of establishing
693 this collection.
694
695 """
696
697 def _refresh_for_new_column(self, column):
698 """Given a column added to the .c collection of an underlying
699 selectable, produce the local version of that column, assuming this
700 selectable ultimately should proxy this column.
701
702 this is used to "ping" a derived selectable to add a new column
703 to its .c. collection when a Column has been added to one of the
704 Table objects it ultimtely derives from.
705
706 If the given selectable hasn't populated its .c. collection yet,
707 it should at least pass on the message to the contained selectables,
708 but it will return None.
709
710 This method is currently used by Declarative to allow Table
711 columns to be added to a partially constructed inheritance
712 mapping that may have already produced joins. The method
713 isn't public right now, as the full span of implications
714 and/or caveats aren't yet clear.
715
716 It's also possible that this functionality could be invoked by
717 default via an event, which would require that
718 selectables maintain a weak referencing collection of all
719 derivations.
720
721 """
722 if not self._cols_populated:
723 return None
724 elif column.key in self.columns and self.columns[column.key] is column:
725 return column
726 else:
727 return None
728
729
730class Join(FromClause):
731 """Represent a ``JOIN`` construct between two
732 :class:`_expression.FromClause` elements.
733
734 The public constructor function for :class:`_expression.Join`
735 is the module-level
736 :func:`_expression.join()` function, as well as the
737 :meth:`_expression.FromClause.join` method
738 of any :class:`_expression.FromClause` (e.g. such as
739 :class:`_schema.Table`).
740
741 .. seealso::
742
743 :func:`_expression.join`
744
745 :meth:`_expression.FromClause.join`
746
747 """
748
749 __visit_name__ = "join"
750
751 _is_join = True
752
753 def __init__(self, left, right, onclause=None, isouter=False, full=False):
754 """Construct a new :class:`_expression.Join`.
755
756 The usual entrypoint here is the :func:`_expression.join`
757 function or the :meth:`_expression.FromClause.join` method of any
758 :class:`_expression.FromClause` object.
759
760 """
761 self.left = _interpret_as_from(left)
762 self.right = _interpret_as_from(right).self_group()
763
764 if onclause is None:
765 self.onclause = self._match_primaries(self.left, self.right)
766 else:
767 self.onclause = onclause
768
769 self.isouter = isouter
770 self.full = full
771
772 @classmethod
773 def _create_outerjoin(cls, left, right, onclause=None, full=False):
774 """Return an ``OUTER JOIN`` clause element.
775
776 The returned object is an instance of :class:`_expression.Join`.
777
778 Similar functionality is also available via the
779 :meth:`_expression.FromClause.outerjoin` method on any
780 :class:`_expression.FromClause`.
781
782 :param left: The left side of the join.
783
784 :param right: The right side of the join.
785
786 :param onclause: Optional criterion for the ``ON`` clause, is
787 derived from foreign key relationships established between
788 left and right otherwise.
789
790 To chain joins together, use the :meth:`_expression.FromClause.join`
791 or
792 :meth:`_expression.FromClause.outerjoin` methods on the resulting
793 :class:`_expression.Join` object.
794
795 """
796 return cls(left, right, onclause, isouter=True, full=full)
797
798 @classmethod
799 def _create_join(
800 cls, left, right, onclause=None, isouter=False, full=False
801 ):
802 """Produce a :class:`_expression.Join` object, given two
803 :class:`_expression.FromClause`
804 expressions.
805
806 E.g.::
807
808 j = join(user_table, address_table,
809 user_table.c.id == address_table.c.user_id)
810 stmt = select([user_table]).select_from(j)
811
812 would emit SQL along the lines of::
813
814 SELECT user.id, user.name FROM user
815 JOIN address ON user.id = address.user_id
816
817 Similar functionality is available given any
818 :class:`_expression.FromClause` object (e.g. such as a
819 :class:`_schema.Table`) using
820 the :meth:`_expression.FromClause.join` method.
821
822 :param left: The left side of the join.
823
824 :param right: the right side of the join; this is any
825 :class:`_expression.FromClause` object such as a
826 :class:`_schema.Table` object, and
827 may also be a selectable-compatible object such as an ORM-mapped
828 class.
829
830 :param onclause: a SQL expression representing the ON clause of the
831 join. If left at ``None``, :meth:`_expression.FromClause.join`
832 will attempt to
833 join the two tables based on a foreign key relationship.
834
835 :param isouter: if True, render a LEFT OUTER JOIN, instead of JOIN.
836
837 :param full: if True, render a FULL OUTER JOIN, instead of JOIN.
838
839 .. versionadded:: 1.1
840
841 .. seealso::
842
843 :meth:`_expression.FromClause.join` - method form,
844 based on a given left side.
845
846 :class:`_expression.Join` - the type of object produced.
847
848 """
849
850 return cls(left, right, onclause, isouter, full)
851
852 @property
853 def description(self):
854 return "Join object on %s(%d) and %s(%d)" % (
855 self.left.description,
856 id(self.left),
857 self.right.description,
858 id(self.right),
859 )
860
861 def is_derived_from(self, fromclause):
862 return (
863 fromclause is self
864 or self.left.is_derived_from(fromclause)
865 or self.right.is_derived_from(fromclause)
866 )
867
868 def self_group(self, against=None):
869 return FromGrouping(self)
870
871 @util.dependencies("sqlalchemy.sql.util")
872 def _populate_column_collection(self, sqlutil):
873 columns = [c for c in self.left.columns] + [
874 c for c in self.right.columns
875 ]
876
877 self.primary_key.extend(
878 sqlutil.reduce_columns(
879 (c for c in columns if c.primary_key), self.onclause
880 )
881 )
882 self._columns.update((col._label, col) for col in columns)
883 self.foreign_keys.update(
884 itertools.chain(*[col.foreign_keys for col in columns])
885 )
886
887 def _refresh_for_new_column(self, column):
888 col = self.left._refresh_for_new_column(column)
889 if col is None:
890 col = self.right._refresh_for_new_column(column)
891 if col is not None:
892 if self._cols_populated:
893 self._columns[col._label] = col
894 self.foreign_keys.update(col.foreign_keys)
895 if col.primary_key:
896 self.primary_key.add(col)
897 return col
898 return None
899
900 def _copy_internals(self, clone=_clone, **kw):
901 self._reset_exported()
902 self.left = clone(self.left, **kw)
903 self.right = clone(self.right, **kw)
904 self.onclause = clone(self.onclause, **kw)
905
906 def get_children(self, **kwargs):
907 return self.left, self.right, self.onclause
908
909 def _match_primaries(self, left, right):
910 if isinstance(left, Join):
911 left_right = left.right
912 else:
913 left_right = None
914 return self._join_condition(left, right, a_subset=left_right)
915
916 @classmethod
917 @util.deprecated_params(
918 ignore_nonexistent_tables=(
919 "0.9",
920 "The :paramref:`.join_condition.ignore_nonexistent_tables` "
921 "parameter is deprecated and will be removed in a future "
922 "release. Tables outside of the two tables being handled "
923 "are no longer considered.",
924 )
925 )
926 def _join_condition(
927 cls,
928 a,
929 b,
930 ignore_nonexistent_tables=False,
931 a_subset=None,
932 consider_as_foreign_keys=None,
933 ):
934 """Create a join condition between two tables or selectables.
935
936 e.g.::
937
938 join_condition(tablea, tableb)
939
940 would produce an expression along the lines of::
941
942 tablea.c.id==tableb.c.tablea_id
943
944 The join is determined based on the foreign key relationships
945 between the two selectables. If there are multiple ways
946 to join, or no way to join, an error is raised.
947
948 :param ignore_nonexistent_tables: unused - tables outside of the
949 two tables being handled are not considered.
950
951 :param a_subset: An optional expression that is a sub-component
952 of ``a``. An attempt will be made to join to just this sub-component
953 first before looking at the full ``a`` construct, and if found
954 will be successful even if there are other ways to join to ``a``.
955 This allows the "right side" of a join to be passed thereby
956 providing a "natural join".
957
958 """
959 constraints = cls._joincond_scan_left_right(
960 a, a_subset, b, consider_as_foreign_keys
961 )
962
963 if len(constraints) > 1:
964 cls._joincond_trim_constraints(
965 a, b, constraints, consider_as_foreign_keys
966 )
967
968 if len(constraints) == 0:
969 if isinstance(b, FromGrouping):
970 hint = (
971 " Perhaps you meant to convert the right side to a "
972 "subquery using alias()?"
973 )
974 else:
975 hint = ""
976 raise exc.NoForeignKeysError(
977 "Can't find any foreign key relationships "
978 "between '%s' and '%s'.%s"
979 % (a.description, b.description, hint)
980 )
981
982 crit = [(x == y) for x, y in list(constraints.values())[0]]
983 if len(crit) == 1:
984 return crit[0]
985 else:
986 return and_(*crit)
987
988 @classmethod
989 def _can_join(cls, left, right, consider_as_foreign_keys=None):
990 if isinstance(left, Join):
991 left_right = left.right
992 else:
993 left_right = None
994
995 constraints = cls._joincond_scan_left_right(
996 a=left,
997 b=right,
998 a_subset=left_right,
999 consider_as_foreign_keys=consider_as_foreign_keys,
1000 )
1001
1002 return bool(constraints)
1003
1004 @classmethod
1005 @util.dependencies("sqlalchemy.sql.util")
1006 def _joincond_scan_left_right(
1007 cls, sql_util, a, a_subset, b, consider_as_foreign_keys
1008 ):
1009 constraints = collections.defaultdict(list)
1010
1011 for left in (a_subset, a):
1012 if left is None:
1013 continue
1014 for fk in sorted(
1015 b.foreign_keys, key=lambda fk: fk.parent._creation_order
1016 ):
1017 if (
1018 consider_as_foreign_keys is not None
1019 and fk.parent not in consider_as_foreign_keys
1020 ):
1021 continue
1022 try:
1023 col = fk.get_referent(left)
1024 except exc.NoReferenceError as nrte:
1025 table_names = {t.name for t in sql_util.find_tables(left)}
1026 if nrte.table_name in table_names:
1027 raise
1028 else:
1029 continue
1030
1031 if col is not None:
1032 constraints[fk.constraint].append((col, fk.parent))
1033 if left is not b:
1034 for fk in sorted(
1035 left.foreign_keys, key=lambda fk: fk.parent._creation_order
1036 ):
1037 if (
1038 consider_as_foreign_keys is not None
1039 and fk.parent not in consider_as_foreign_keys
1040 ):
1041 continue
1042 try:
1043 col = fk.get_referent(b)
1044 except exc.NoReferenceError as nrte:
1045 table_names = {t.name for t in sql_util.find_tables(b)}
1046 if nrte.table_name in table_names:
1047 raise
1048 else:
1049 continue
1050
1051 if col is not None:
1052 constraints[fk.constraint].append((col, fk.parent))
1053 if constraints:
1054 break
1055 return constraints
1056
1057 @classmethod
1058 def _joincond_trim_constraints(
1059 cls, a, b, constraints, consider_as_foreign_keys
1060 ):
1061 # more than one constraint matched. narrow down the list
1062 # to include just those FKCs that match exactly to
1063 # "consider_as_foreign_keys".
1064 if consider_as_foreign_keys:
1065 for const in list(constraints):
1066 if set(f.parent for f in const.elements) != set(
1067 consider_as_foreign_keys
1068 ):
1069 del constraints[const]
1070
1071 # if still multiple constraints, but
1072 # they all refer to the exact same end result, use it.
1073 if len(constraints) > 1:
1074 dedupe = set(tuple(crit) for crit in constraints.values())
1075 if len(dedupe) == 1:
1076 key = list(constraints)[0]
1077 constraints = {key: constraints[key]}
1078
1079 if len(constraints) != 1:
1080 raise exc.AmbiguousForeignKeysError(
1081 "Can't determine join between '%s' and '%s'; "
1082 "tables have more than one foreign key "
1083 "constraint relationship between them. "
1084 "Please specify the 'onclause' of this "
1085 "join explicitly." % (a.description, b.description)
1086 )
1087
1088 def select(self, whereclause=None, **kwargs):
1089 r"""Create a :class:`_expression.Select` from this
1090 :class:`_expression.Join`.
1091
1092 The equivalent long-hand form, given a :class:`_expression.Join`
1093 object
1094 ``j``, is::
1095
1096 from sqlalchemy import select
1097 j = select([j.left, j.right], **kw).\
1098 where(whereclause).\
1099 select_from(j)
1100
1101 :param whereclause: the WHERE criterion that will be sent to
1102 the :func:`select()` function
1103
1104 :param \**kwargs: all other kwargs are sent to the
1105 underlying :func:`select()` function.
1106
1107 """
1108 collist = [self.left, self.right]
1109
1110 return Select(collist, whereclause, from_obj=[self], **kwargs)
1111
1112 @property
1113 def bind(self):
1114 return self.left.bind or self.right.bind
1115
1116 @util.dependencies("sqlalchemy.sql.util")
1117 def alias(self, sqlutil, name=None, flat=False):
1118 r"""Return an alias of this :class:`_expression.Join`.
1119
1120 The default behavior here is to first produce a SELECT
1121 construct from this :class:`_expression.Join`, then to produce an
1122 :class:`_expression.Alias` from that. So given a join of the form::
1123
1124 j = table_a.join(table_b, table_a.c.id == table_b.c.a_id)
1125
1126 The JOIN by itself would look like::
1127
1128 table_a JOIN table_b ON table_a.id = table_b.a_id
1129
1130 Whereas the alias of the above, ``j.alias()``, would in a
1131 SELECT context look like::
1132
1133 (SELECT table_a.id AS table_a_id, table_b.id AS table_b_id,
1134 table_b.a_id AS table_b_a_id
1135 FROM table_a
1136 JOIN table_b ON table_a.id = table_b.a_id) AS anon_1
1137
1138 The equivalent long-hand form, given a :class:`_expression.Join`
1139 object
1140 ``j``, is::
1141
1142 from sqlalchemy import select, alias
1143 j = alias(
1144 select([j.left, j.right]).\
1145 select_from(j).\
1146 with_labels(True).\
1147 correlate(False),
1148 name=name
1149 )
1150
1151 The selectable produced by :meth:`_expression.Join.alias`
1152 features the same
1153 columns as that of the two individual selectables presented under
1154 a single name - the individual columns are "auto-labeled", meaning
1155 the ``.c.`` collection of the resulting :class:`_expression.Alias`
1156 represents
1157 the names of the individual columns using a
1158 ``<tablename>_<columname>`` scheme::
1159
1160 j.c.table_a_id
1161 j.c.table_b_a_id
1162
1163 :meth:`_expression.Join.alias` also features an alternate
1164 option for aliasing joins which produces no enclosing SELECT and
1165 does not normally apply labels to the column names. The
1166 ``flat=True`` option will call :meth:`_expression.FromClause.alias`
1167 against the left and right sides individually.
1168 Using this option, no new ``SELECT`` is produced;
1169 we instead, from a construct as below::
1170
1171 j = table_a.join(table_b, table_a.c.id == table_b.c.a_id)
1172 j = j.alias(flat=True)
1173
1174 we get a result like this::
1175
1176 table_a AS table_a_1 JOIN table_b AS table_b_1 ON
1177 table_a_1.id = table_b_1.a_id
1178
1179 The ``flat=True`` argument is also propagated to the contained
1180 selectables, so that a composite join such as::
1181
1182 j = table_a.join(
1183 table_b.join(table_c,
1184 table_b.c.id == table_c.c.b_id),
1185 table_b.c.a_id == table_a.c.id
1186 ).alias(flat=True)
1187
1188 Will produce an expression like::
1189
1190 table_a AS table_a_1 JOIN (
1191 table_b AS table_b_1 JOIN table_c AS table_c_1
1192 ON table_b_1.id = table_c_1.b_id
1193 ) ON table_a_1.id = table_b_1.a_id
1194
1195 The standalone :func:`_expression.alias` function as well as the
1196 base :meth:`_expression.FromClause.alias`
1197 method also support the ``flat=True``
1198 argument as a no-op, so that the argument can be passed to the
1199 ``alias()`` method of any selectable.
1200
1201 .. versionadded:: 0.9.0 Added the ``flat=True`` option to create
1202 "aliases" of joins without enclosing inside of a SELECT
1203 subquery.
1204
1205 :param name: name given to the alias.
1206
1207 :param flat: if True, produce an alias of the left and right
1208 sides of this :class:`_expression.Join` and return the join of those
1209 two selectables. This produces join expression that does not
1210 include an enclosing SELECT.
1211
1212 .. versionadded:: 0.9.0
1213
1214 .. seealso::
1215
1216 :ref:`core_tutorial_aliases`
1217
1218 :func:`_expression.alias`
1219
1220 """
1221 if flat:
1222 assert name is None, "Can't send name argument with flat"
1223 left_a, right_a = (
1224 self.left.alias(flat=True),
1225 self.right.alias(flat=True),
1226 )
1227 adapter = sqlutil.ClauseAdapter(left_a).chain(
1228 sqlutil.ClauseAdapter(right_a)
1229 )
1230
1231 return left_a.join(
1232 right_a,
1233 adapter.traverse(self.onclause),
1234 isouter=self.isouter,
1235 full=self.full,
1236 )
1237 else:
1238 return self.select(use_labels=True, correlate=False).alias(name)
1239
1240 @property
1241 def _hide_froms(self):
1242 return itertools.chain(
1243 *[_from_objects(x.left, x.right) for x in self._cloned_set]
1244 )
1245
1246 @property
1247 def _from_objects(self):
1248 return (
1249 [self]
1250 + self.onclause._from_objects
1251 + self.left._from_objects
1252 + self.right._from_objects
1253 )
1254
1255
1256class Alias(FromClause):
1257 """Represents an table or selectable alias (AS).
1258
1259 Represents an alias, as typically applied to any table or
1260 sub-select within a SQL statement using the ``AS`` keyword (or
1261 without the keyword on certain databases such as Oracle).
1262
1263 This object is constructed from the :func:`_expression.alias` module
1264 level function as well as the :meth:`_expression.FromClause.alias`
1265 method available
1266 on all :class:`_expression.FromClause` subclasses.
1267
1268 """
1269
1270 __visit_name__ = "alias"
1271 named_with_column = True
1272
1273 _is_from_container = True
1274
1275 def __init__(self, *arg, **kw):
1276 raise NotImplementedError(
1277 "The %s class is not intended to be constructed "
1278 "directly. Please use the %s() standalone "
1279 "function or the %s() method available from appropriate "
1280 "selectable objects."
1281 % (
1282 self.__class__.__name__,
1283 self.__class__.__name__.lower(),
1284 self.__class__.__name__.lower(),
1285 )
1286 )
1287
1288 @classmethod
1289 def _construct(cls, *arg, **kw):
1290 obj = cls.__new__(cls)
1291 obj._init(*arg, **kw)
1292 return obj
1293
1294 @classmethod
1295 def _factory(cls, selectable, name=None, flat=False):
1296 """Return an :class:`_expression.Alias` object.
1297
1298 An :class:`_expression.Alias` represents any
1299 :class:`_expression.FromClause`
1300 with an alternate name assigned within SQL, typically using the ``AS``
1301 clause when generated, e.g. ``SELECT * FROM table AS aliasname``.
1302
1303 Similar functionality is available via the
1304 :meth:`_expression.FromClause.alias`
1305 method available on all :class:`_expression.FromClause` subclasses.
1306 In terms of
1307 a SELECT object as generated from the :func:`_expression.select`
1308 function, the :meth:`_expression.SelectBase.alias` method returns an
1309 :class:`_expression.Alias` or similar object which represents a named,
1310 parenthesized subquery.
1311
1312 When an :class:`_expression.Alias` is created from a
1313 :class:`_schema.Table` object,
1314 this has the effect of the table being rendered
1315 as ``tablename AS aliasname`` in a SELECT statement.
1316
1317 For :func:`_expression.select` objects, the effect is that of
1318 creating a named subquery, i.e. ``(select ...) AS aliasname``.
1319
1320 The ``name`` parameter is optional, and provides the name
1321 to use in the rendered SQL. If blank, an "anonymous" name
1322 will be deterministically generated at compile time.
1323 Deterministic means the name is guaranteed to be unique against
1324 other constructs used in the same statement, and will also be the
1325 same name for each successive compilation of the same statement
1326 object.
1327
1328 :param selectable: any :class:`_expression.FromClause` subclass,
1329 such as a table, select statement, etc.
1330
1331 :param name: string name to be assigned as the alias.
1332 If ``None``, a name will be deterministically generated
1333 at compile time.
1334
1335 :param flat: Will be passed through to if the given selectable
1336 is an instance of :class:`_expression.Join` - see
1337 :meth:`_expression.Join.alias`
1338 for details.
1339
1340 .. versionadded:: 0.9.0
1341
1342 """
1343 return _interpret_as_from(selectable).alias(name=name, flat=flat)
1344
1345 def _init(self, selectable, name=None):
1346 baseselectable = selectable
1347 while isinstance(baseselectable, Alias):
1348 baseselectable = baseselectable.element
1349 self.original = baseselectable
1350 self.supports_execution = baseselectable.supports_execution
1351 if self.supports_execution:
1352 self._execution_options = baseselectable._execution_options
1353 self.element = selectable
1354 if name is None:
1355 if self.original.named_with_column:
1356 name = getattr(self.original, "name", None)
1357 name = _anonymous_label("%%(%d %s)s" % (id(self), name or "anon"))
1358 self.name = name
1359
1360 def self_group(self, against=None):
1361 if (
1362 isinstance(against, CompoundSelect)
1363 and isinstance(self.original, Select)
1364 and self.original._needs_parens_for_grouping()
1365 ):
1366 return FromGrouping(self)
1367
1368 return super(Alias, self).self_group(against=against)
1369
1370 @property
1371 def description(self):
1372 if util.py3k:
1373 return self.name
1374 else:
1375 return self.name.encode("ascii", "backslashreplace")
1376
1377 def as_scalar(self):
1378 try:
1379 return self.element.as_scalar()
1380 except AttributeError as err:
1381 util.raise_(
1382 AttributeError(
1383 "Element %s does not support "
1384 "'as_scalar()'" % self.element
1385 ),
1386 replace_context=err,
1387 )
1388
1389 def is_derived_from(self, fromclause):
1390 if fromclause in self._cloned_set:
1391 return True
1392 return self.element.is_derived_from(fromclause)
1393
1394 def _populate_column_collection(self):
1395 for col in self.element.columns._all_columns:
1396 col._make_proxy(self)
1397
1398 def _refresh_for_new_column(self, column):
1399 col = self.element._refresh_for_new_column(column)
1400 if col is not None:
1401 if not self._cols_populated:
1402 return None
1403 else:
1404 return col._make_proxy(self)
1405 else:
1406 return None
1407
1408 def _copy_internals(self, clone=_clone, **kw):
1409 # don't apply anything to an aliased Table
1410 # for now. May want to drive this from
1411 # the given **kw.
1412 if isinstance(self.element, TableClause):
1413 return
1414 self._reset_exported()
1415 self.element = clone(self.element, **kw)
1416 baseselectable = self.element
1417 while isinstance(baseselectable, Alias):
1418 baseselectable = baseselectable.element
1419 self.original = baseselectable
1420
1421 def get_children(self, column_collections=True, **kw):
1422 if column_collections:
1423 for c in self.c:
1424 yield c
1425 yield self.element
1426
1427 @property
1428 def _from_objects(self):
1429 return [self]
1430
1431 @property
1432 def bind(self):
1433 return self.element.bind
1434
1435
1436class Lateral(Alias):
1437 """Represent a LATERAL subquery.
1438
1439 This object is constructed from the :func:`_expression.lateral` module
1440 level function as well as the :meth:`_expression.FromClause.lateral`
1441 method available
1442 on all :class:`_expression.FromClause` subclasses.
1443
1444 While LATERAL is part of the SQL standard, currently only more recent
1445 PostgreSQL versions provide support for this keyword.
1446
1447 .. versionadded:: 1.1
1448
1449 .. seealso::
1450
1451 :ref:`lateral_selects` - overview of usage.
1452
1453 """
1454
1455 __visit_name__ = "lateral"
1456 _is_lateral = True
1457
1458 @classmethod
1459 def _factory(cls, selectable, name=None):
1460 """Return a :class:`_expression.Lateral` object.
1461
1462 :class:`_expression.Lateral` is an :class:`_expression.Alias`
1463 subclass that represents
1464 a subquery with the LATERAL keyword applied to it.
1465
1466 The special behavior of a LATERAL subquery is that it appears in the
1467 FROM clause of an enclosing SELECT, but may correlate to other
1468 FROM clauses of that SELECT. It is a special case of subquery
1469 only supported by a small number of backends, currently more recent
1470 PostgreSQL versions.
1471
1472 .. versionadded:: 1.1
1473
1474 .. seealso::
1475
1476 :ref:`lateral_selects` - overview of usage.
1477
1478 """
1479 return _interpret_as_from(selectable).lateral(name=name)
1480
1481
1482class TableSample(Alias):
1483 """Represent a TABLESAMPLE clause.
1484
1485 This object is constructed from the :func:`_expression.tablesample` module
1486 level function as well as the :meth:`_expression.FromClause.tablesample`
1487 method
1488 available on all :class:`_expression.FromClause` subclasses.
1489
1490 .. versionadded:: 1.1
1491
1492 .. seealso::
1493
1494 :func:`_expression.tablesample`
1495
1496 """
1497
1498 __visit_name__ = "tablesample"
1499
1500 @classmethod
1501 def _factory(cls, selectable, sampling, name=None, seed=None):
1502 """Return a :class:`_expression.TableSample` object.
1503
1504 :class:`_expression.TableSample` is an :class:`_expression.Alias`
1505 subclass that represents
1506 a table with the TABLESAMPLE clause applied to it.
1507 :func:`_expression.tablesample`
1508 is also available from the :class:`_expression.FromClause`
1509 class via the
1510 :meth:`_expression.FromClause.tablesample` method.
1511
1512 The TABLESAMPLE clause allows selecting a randomly selected approximate
1513 percentage of rows from a table. It supports multiple sampling methods,
1514 most commonly BERNOULLI and SYSTEM.
1515
1516 e.g.::
1517
1518 from sqlalchemy import func
1519
1520 selectable = people.tablesample(
1521 func.bernoulli(1),
1522 name='alias',
1523 seed=func.random())
1524 stmt = select([selectable.c.people_id])
1525
1526 Assuming ``people`` with a column ``people_id``, the above
1527 statement would render as::
1528
1529 SELECT alias.people_id FROM
1530 people AS alias TABLESAMPLE bernoulli(:bernoulli_1)
1531 REPEATABLE (random())
1532
1533 .. versionadded:: 1.1
1534
1535 :param sampling: a ``float`` percentage between 0 and 100 or
1536 :class:`_functions.Function`.
1537
1538 :param name: optional alias name
1539
1540 :param seed: any real-valued SQL expression. When specified, the
1541 REPEATABLE sub-clause is also rendered.
1542
1543 """
1544 return _interpret_as_from(selectable).tablesample(
1545 sampling, name=name, seed=seed
1546 )
1547
1548 def _init(self, selectable, sampling, name=None, seed=None):
1549 self.sampling = sampling
1550 self.seed = seed
1551 super(TableSample, self)._init(selectable, name=name)
1552
1553 @util.dependencies("sqlalchemy.sql.functions")
1554 def _get_method(self, functions):
1555 if isinstance(self.sampling, functions.Function):
1556 return self.sampling
1557 else:
1558 return functions.func.system(self.sampling)
1559
1560
1561class CTE(Generative, HasPrefixes, HasSuffixes, Alias):
1562 """Represent a Common Table Expression.
1563
1564 The :class:`_expression.CTE` object is obtained using the
1565 :meth:`_expression.SelectBase.cte` method from any selectable.
1566 See that method for complete examples.
1567
1568 """
1569
1570 __visit_name__ = "cte"
1571
1572 @classmethod
1573 def _factory(cls, selectable, name=None, recursive=False):
1574 r"""Return a new :class:`_expression.CTE`,
1575 or Common Table Expression instance.
1576
1577 Please see :meth:`_expression.HasCTE.cte` for detail on CTE usage.
1578
1579 """
1580 return _interpret_as_from(selectable).cte(
1581 name=name, recursive=recursive
1582 )
1583
1584 def _init(
1585 self,
1586 selectable,
1587 name=None,
1588 recursive=False,
1589 _cte_alias=None,
1590 _restates=frozenset(),
1591 _prefixes=None,
1592 _suffixes=None,
1593 ):
1594 self.recursive = recursive
1595 self._cte_alias = _cte_alias
1596 self._restates = _restates
1597 if _prefixes:
1598 self._prefixes = _prefixes
1599 if _suffixes:
1600 self._suffixes = _suffixes
1601 super(CTE, self)._init(selectable, name=name)
1602
1603 def _copy_internals(self, clone=_clone, **kw):
1604 super(CTE, self)._copy_internals(clone, **kw)
1605 if self._cte_alias is not None:
1606 self._cte_alias = clone(self._cte_alias, **kw)
1607 self._restates = frozenset(
1608 [clone(elem, **kw) for elem in self._restates]
1609 )
1610
1611 @util.dependencies("sqlalchemy.sql.dml")
1612 def _populate_column_collection(self, dml):
1613 if isinstance(self.element, dml.UpdateBase):
1614 for col in self.element._returning:
1615 col._make_proxy(self)
1616 else:
1617 for col in self.element.columns._all_columns:
1618 col._make_proxy(self)
1619
1620 def alias(self, name=None, flat=False):
1621 """Return an :class:`_expression.Alias` of this
1622 :class:`_expression.CTE`.
1623
1624 This method is a CTE-specific specialization of the
1625 :meth:`_expression.FromClause.alias` method.
1626
1627 .. seealso::
1628
1629 :ref:`core_tutorial_aliases`
1630
1631 :func:`_expression.alias`
1632
1633 """
1634 return CTE._construct(
1635 self.original,
1636 name=name,
1637 recursive=self.recursive,
1638 _cte_alias=self,
1639 _prefixes=self._prefixes,
1640 _suffixes=self._suffixes,
1641 )
1642
1643 def union(self, other):
1644 return CTE._construct(
1645 self.original.union(other),
1646 name=self.name,
1647 recursive=self.recursive,
1648 _restates=self._restates.union([self]),
1649 _prefixes=self._prefixes,
1650 _suffixes=self._suffixes,
1651 )
1652
1653 def union_all(self, other):
1654 return CTE._construct(
1655 self.original.union_all(other),
1656 name=self.name,
1657 recursive=self.recursive,
1658 _restates=self._restates.union([self]),
1659 _prefixes=self._prefixes,
1660 _suffixes=self._suffixes,
1661 )
1662
1663
1664class HasCTE(object):
1665 """Mixin that declares a class to include CTE support.
1666
1667 .. versionadded:: 1.1
1668
1669 """
1670
1671 def cte(self, name=None, recursive=False):
1672 r"""Return a new :class:`_expression.CTE`,
1673 or Common Table Expression instance.
1674
1675 Common table expressions are a SQL standard whereby SELECT
1676 statements can draw upon secondary statements specified along
1677 with the primary statement, using a clause called "WITH".
1678 Special semantics regarding UNION can also be employed to
1679 allow "recursive" queries, where a SELECT statement can draw
1680 upon the set of rows that have previously been selected.
1681
1682 CTEs can also be applied to DML constructs UPDATE, INSERT
1683 and DELETE on some databases, both as a source of CTE rows
1684 when combined with RETURNING, as well as a consumer of
1685 CTE rows.
1686
1687 .. versionchanged:: 1.1 Added support for UPDATE/INSERT/DELETE as
1688 CTE, CTEs added to UPDATE/INSERT/DELETE.
1689
1690 SQLAlchemy detects :class:`_expression.CTE` objects, which are treated
1691 similarly to :class:`_expression.Alias` objects, as special elements
1692 to be delivered to the FROM clause of the statement as well
1693 as to a WITH clause at the top of the statement.
1694
1695 For special prefixes such as PostgreSQL "MATERIALIZED" and
1696 "NOT MATERIALIZED", the :meth:`_expression.CTE.prefix_with`
1697 method may be
1698 used to establish these.
1699
1700 .. versionchanged:: 1.3.13 Added support for prefixes.
1701 In particular - MATERIALIZED and NOT MATERIALIZED.
1702
1703 :param name: name given to the common table expression. Like
1704 :meth:`_expression.FromClause.alias`, the name can be left as
1705 ``None`` in which case an anonymous symbol will be used at query
1706 compile time.
1707 :param recursive: if ``True``, will render ``WITH RECURSIVE``.
1708 A recursive common table expression is intended to be used in
1709 conjunction with UNION ALL in order to derive rows
1710 from those already selected.
1711
1712 The following examples include two from PostgreSQL's documentation at
1713 http://www.postgresql.org/docs/current/static/queries-with.html,
1714 as well as additional examples.
1715
1716 Example 1, non recursive::
1717
1718 from sqlalchemy import (Table, Column, String, Integer,
1719 MetaData, select, func)
1720
1721 metadata = MetaData()
1722
1723 orders = Table('orders', metadata,
1724 Column('region', String),
1725 Column('amount', Integer),
1726 Column('product', String),
1727 Column('quantity', Integer)
1728 )
1729
1730 regional_sales = select([
1731 orders.c.region,
1732 func.sum(orders.c.amount).label('total_sales')
1733 ]).group_by(orders.c.region).cte("regional_sales")
1734
1735
1736 top_regions = select([regional_sales.c.region]).\
1737 where(
1738 regional_sales.c.total_sales >
1739 select([
1740 func.sum(regional_sales.c.total_sales)/10
1741 ])
1742 ).cte("top_regions")
1743
1744 statement = select([
1745 orders.c.region,
1746 orders.c.product,
1747 func.sum(orders.c.quantity).label("product_units"),
1748 func.sum(orders.c.amount).label("product_sales")
1749 ]).where(orders.c.region.in_(
1750 select([top_regions.c.region])
1751 )).group_by(orders.c.region, orders.c.product)
1752
1753 result = conn.execute(statement).fetchall()
1754
1755 Example 2, WITH RECURSIVE::
1756
1757 from sqlalchemy import (Table, Column, String, Integer,
1758 MetaData, select, func)
1759
1760 metadata = MetaData()
1761
1762 parts = Table('parts', metadata,
1763 Column('part', String),
1764 Column('sub_part', String),
1765 Column('quantity', Integer),
1766 )
1767
1768 included_parts = select([
1769 parts.c.sub_part,
1770 parts.c.part,
1771 parts.c.quantity]).\
1772 where(parts.c.part=='our part').\
1773 cte(recursive=True)
1774
1775
1776 incl_alias = included_parts.alias()
1777 parts_alias = parts.alias()
1778 included_parts = included_parts.union_all(
1779 select([
1780 parts_alias.c.sub_part,
1781 parts_alias.c.part,
1782 parts_alias.c.quantity
1783 ]).
1784 where(parts_alias.c.part==incl_alias.c.sub_part)
1785 )
1786
1787 statement = select([
1788 included_parts.c.sub_part,
1789 func.sum(included_parts.c.quantity).
1790 label('total_quantity')
1791 ]).\
1792 group_by(included_parts.c.sub_part)
1793
1794 result = conn.execute(statement).fetchall()
1795
1796 Example 3, an upsert using UPDATE and INSERT with CTEs::
1797
1798 from datetime import date
1799 from sqlalchemy import (MetaData, Table, Column, Integer,
1800 Date, select, literal, and_, exists)
1801
1802 metadata = MetaData()
1803
1804 visitors = Table('visitors', metadata,
1805 Column('product_id', Integer, primary_key=True),
1806 Column('date', Date, primary_key=True),
1807 Column('count', Integer),
1808 )
1809
1810 # add 5 visitors for the product_id == 1
1811 product_id = 1
1812 day = date.today()
1813 count = 5
1814
1815 update_cte = (
1816 visitors.update()
1817 .where(and_(visitors.c.product_id == product_id,
1818 visitors.c.date == day))
1819 .values(count=visitors.c.count + count)
1820 .returning(literal(1))
1821 .cte('update_cte')
1822 )
1823
1824 upsert = visitors.insert().from_select(
1825 [visitors.c.product_id, visitors.c.date, visitors.c.count],
1826 select([literal(product_id), literal(day), literal(count)])
1827 .where(~exists(update_cte.select()))
1828 )
1829
1830 connection.execute(upsert)
1831
1832 .. seealso::
1833
1834 :meth:`.orm.query.Query.cte` - ORM version of
1835 :meth:`_expression.HasCTE.cte`.
1836
1837 """
1838 return CTE._construct(self, name=name, recursive=recursive)
1839
1840
1841class FromGrouping(FromClause):
1842 """Represent a grouping of a FROM clause"""
1843
1844 __visit_name__ = "grouping"
1845
1846 def __init__(self, element):
1847 self.element = element
1848
1849 def _init_collections(self):
1850 pass
1851
1852 @property
1853 def columns(self):
1854 return self.element.columns
1855
1856 @property
1857 def primary_key(self):
1858 return self.element.primary_key
1859
1860 @property
1861 def foreign_keys(self):
1862 return self.element.foreign_keys
1863
1864 def is_derived_from(self, element):
1865 return self.element.is_derived_from(element)
1866
1867 def alias(self, **kw):
1868 return FromGrouping(self.element.alias(**kw))
1869
1870 @property
1871 def _hide_froms(self):
1872 return self.element._hide_froms
1873
1874 def get_children(self, **kwargs):
1875 return (self.element,)
1876
1877 def _copy_internals(self, clone=_clone, **kw):
1878 self.element = clone(self.element, **kw)
1879
1880 @property
1881 def _from_objects(self):
1882 return self.element._from_objects
1883
1884 def __getattr__(self, attr):
1885 return getattr(self.element, attr)
1886
1887 def __getstate__(self):
1888 return {"element": self.element}
1889
1890 def __setstate__(self, state):
1891 self.element = state["element"]
1892
1893
1894class TableClause(Immutable, FromClause):
1895 """Represents a minimal "table" construct.
1896
1897 This is a lightweight table object that has only a name, a
1898 collection of columns, which are typically produced
1899 by the :func:`_expression.column` function, and a schema::
1900
1901 from sqlalchemy import table, column
1902
1903 user = table("user",
1904 column("id"),
1905 column("name"),
1906 column("description"),
1907 )
1908
1909 The :class:`_expression.TableClause` construct serves as the base for
1910 the more commonly used :class:`_schema.Table` object, providing
1911 the usual set of :class:`_expression.FromClause` services including
1912 the ``.c.`` collection and statement generation methods.
1913
1914 It does **not** provide all the additional schema-level services
1915 of :class:`_schema.Table`, including constraints, references to other
1916 tables, or support for :class:`_schema.MetaData`-level services.
1917 It's useful
1918 on its own as an ad-hoc construct used to generate quick SQL
1919 statements when a more fully fledged :class:`_schema.Table`
1920 is not on hand.
1921
1922 """
1923
1924 __visit_name__ = "table"
1925
1926 named_with_column = True
1927
1928 implicit_returning = False
1929 """:class:`_expression.TableClause`
1930 doesn't support having a primary key or column
1931 -level defaults, so implicit returning doesn't apply."""
1932
1933 _autoincrement_column = None
1934 """No PK or default support so no autoincrement column."""
1935
1936 def __init__(self, name, *columns, **kw):
1937 """Produce a new :class:`_expression.TableClause`.
1938
1939 The object returned is an instance of
1940 :class:`_expression.TableClause`, which
1941 represents the "syntactical" portion of the schema-level
1942 :class:`_schema.Table` object.
1943 It may be used to construct lightweight table constructs.
1944
1945 .. versionchanged:: 1.0.0 :func:`_expression.table` can now
1946 be imported from the plain ``sqlalchemy`` namespace like any
1947 other SQL element.
1948
1949
1950 :param name: Name of the table.
1951
1952 :param columns: A collection of :func:`_expression.column` constructs.
1953
1954 :param schema: The schema name for this table.
1955
1956 .. versionadded:: 1.3.18 :func:`_expression.table` can now
1957 accept a ``schema`` argument.
1958 """
1959
1960 super(TableClause, self).__init__()
1961 self.name = self.fullname = name
1962 self._columns = ColumnCollection()
1963 self.primary_key = ColumnSet()
1964 self.foreign_keys = set()
1965 for c in columns:
1966 self.append_column(c)
1967
1968 schema = kw.pop("schema", None)
1969 if schema is not None:
1970 self.schema = schema
1971 if kw:
1972 raise exc.ArgumentError("Unsupported argument(s): %s" % list(kw))
1973
1974 def _init_collections(self):
1975 pass
1976
1977 @util.memoized_property
1978 def description(self):
1979 if util.py3k:
1980 return self.name
1981 else:
1982 return self.name.encode("ascii", "backslashreplace")
1983
1984 def append_column(self, c):
1985 existing = c.table
1986 if existing is not None and existing is not self:
1987 raise exc.ArgumentError(
1988 "column object '%s' already assigned to table %r"
1989 % (c.key, getattr(existing, "description", existing))
1990 )
1991
1992 self._columns[c.key] = c
1993 c.table = self
1994
1995 def get_children(self, column_collections=True, **kwargs):
1996 if column_collections:
1997 return [c for c in self.c]
1998 else:
1999 return []
2000
2001 @util.dependencies("sqlalchemy.sql.dml")
2002 def insert(self, dml, values=None, inline=False, **kwargs):
2003 """Generate an :func:`_expression.insert` construct against this
2004 :class:`_expression.TableClause`.
2005
2006 E.g.::
2007
2008 table.insert().values(name='foo')
2009
2010 See :func:`_expression.insert` for argument and usage information.
2011
2012 """
2013
2014 return dml.Insert(self, values=values, inline=inline, **kwargs)
2015
2016 @util.dependencies("sqlalchemy.sql.dml")
2017 def update(
2018 self, dml, whereclause=None, values=None, inline=False, **kwargs
2019 ):
2020 """Generate an :func:`_expression.update` construct against this
2021 :class:`_expression.TableClause`.
2022
2023 E.g.::
2024
2025 table.update().where(table.c.id==7).values(name='foo')
2026
2027 See :func:`_expression.update` for argument and usage information.
2028
2029 """
2030
2031 return dml.Update(
2032 self,
2033 whereclause=whereclause,
2034 values=values,
2035 inline=inline,
2036 **kwargs
2037 )
2038
2039 @util.dependencies("sqlalchemy.sql.dml")
2040 def delete(self, dml, whereclause=None, **kwargs):
2041 """Generate a :func:`_expression.delete` construct against this
2042 :class:`_expression.TableClause`.
2043
2044 E.g.::
2045
2046 table.delete().where(table.c.id==7)
2047
2048 See :func:`_expression.delete` for argument and usage information.
2049
2050 """
2051
2052 return dml.Delete(self, whereclause, **kwargs)
2053
2054 @property
2055 def _from_objects(self):
2056 return [self]
2057
2058
2059class ForUpdateArg(ClauseElement):
2060 @classmethod
2061 def parse_legacy_select(self, arg):
2062 """Parse the for_update argument of :func:`_expression.select`.
2063
2064 :param mode: Defines the lockmode to use.
2065
2066 ``None`` - translates to no lockmode
2067
2068 ``'update'`` - translates to ``FOR UPDATE``
2069 (standard SQL, supported by most dialects)
2070
2071 ``'nowait'`` - translates to ``FOR UPDATE NOWAIT``
2072 (supported by Oracle, PostgreSQL 8.1 upwards)
2073
2074 ``'read'`` - translates to ``LOCK IN SHARE MODE`` (for MySQL),
2075 and ``FOR SHARE`` (for PostgreSQL)
2076
2077 ``'read_nowait'`` - translates to ``FOR SHARE NOWAIT``
2078 (supported by PostgreSQL). ``FOR SHARE`` and
2079 ``FOR SHARE NOWAIT`` (PostgreSQL).
2080
2081 """
2082 if arg in (None, False):
2083 return None
2084
2085 nowait = read = False
2086 if arg == "nowait":
2087 nowait = True
2088 elif arg == "read":
2089 read = True
2090 elif arg == "read_nowait":
2091 read = nowait = True
2092 elif arg is not True:
2093 raise exc.ArgumentError("Unknown for_update argument: %r" % arg)
2094
2095 return ForUpdateArg(read=read, nowait=nowait)
2096
2097 @property
2098 def legacy_for_update_value(self):
2099 if self.read and not self.nowait:
2100 return "read"
2101 elif self.read and self.nowait:
2102 return "read_nowait"
2103 elif self.nowait:
2104 return "nowait"
2105 else:
2106 return True
2107
2108 def __eq__(self, other):
2109 return (
2110 isinstance(other, ForUpdateArg)
2111 and other.nowait == self.nowait
2112 and other.read == self.read
2113 and other.skip_locked == self.skip_locked
2114 and other.key_share == self.key_share
2115 and other.of is self.of
2116 )
2117
2118 def __hash__(self):
2119 return id(self)
2120
2121 def _copy_internals(self, clone=_clone, **kw):
2122 if self.of is not None:
2123 self.of = [clone(col, **kw) for col in self.of]
2124
2125 def __init__(
2126 self,
2127 nowait=False,
2128 read=False,
2129 of=None,
2130 skip_locked=False,
2131 key_share=False,
2132 ):
2133 """Represents arguments specified to
2134 :meth:`_expression.Select.for_update`.
2135
2136 .. versionadded:: 0.9.0
2137
2138 """
2139
2140 self.nowait = nowait
2141 self.read = read
2142 self.skip_locked = skip_locked
2143 self.key_share = key_share
2144 if of is not None:
2145 self.of = [
2146 _interpret_as_column_or_from(elem) for elem in util.to_list(of)
2147 ]
2148 else:
2149 self.of = None
2150
2151
2152class SelectBase(HasCTE, Executable, FromClause):
2153 """Base class for SELECT statements.
2154
2155
2156 This includes :class:`_expression.Select`,
2157 :class:`_selectable.CompoundSelect` and
2158 :class:`.TextAsFrom`.
2159
2160
2161 """
2162
2163 def as_scalar(self):
2164 """Return a 'scalar' representation of this selectable, which can be
2165 used as a column expression.
2166
2167 Typically, a select statement which has only one column in its columns
2168 clause is eligible to be used as a scalar expression.
2169
2170 The returned object is an instance of
2171 :class:`ScalarSelect`.
2172
2173 """
2174 return ScalarSelect(self)
2175
2176 def label(self, name):
2177 """Return a 'scalar' representation of this selectable, embedded as a
2178 subquery with a label.
2179
2180 .. seealso::
2181
2182 :meth:`_expression.SelectBase.as_scalar`.
2183
2184 """
2185 return self.as_scalar().label(name)
2186
2187 @_generative
2188 @util.deprecated(
2189 "0.6",
2190 message="The :meth:`.SelectBase.autocommit` method is deprecated, "
2191 "and will be removed in a future release. Please use the "
2192 "the :paramref:`.Connection.execution_options.autocommit` "
2193 "parameter in conjunction with the "
2194 ":meth:`.Executable.execution_options` method.",
2195 )
2196 def autocommit(self):
2197 """Return a new selectable with the 'autocommit' flag set to
2198 True.
2199
2200 """
2201
2202 self._execution_options = self._execution_options.union(
2203 {"autocommit": True}
2204 )
2205
2206 def _generate(self):
2207 """Override the default _generate() method to also clear out
2208 exported collections."""
2209
2210 s = self.__class__.__new__(self.__class__)
2211 s.__dict__ = self.__dict__.copy()
2212 s._reset_exported()
2213 return s
2214
2215 @property
2216 def _from_objects(self):
2217 return [self]
2218
2219
2220class GenerativeSelect(SelectBase):
2221 """Base class for SELECT statements where additional elements can be
2222 added.
2223
2224 This serves as the base for :class:`_expression.Select` and
2225 :class:`_selectable.CompoundSelect`
2226 where elements such as ORDER BY, GROUP BY can be added and column
2227 rendering can be controlled. Compare to :class:`.TextAsFrom`, which,
2228 while it subclasses :class:`_expression.SelectBase`
2229 and is also a SELECT construct,
2230 represents a fixed textual string which cannot be altered at this level,
2231 only wrapped as a subquery.
2232
2233 .. versionadded:: 0.9.0 :class:`_expression.GenerativeSelect` was added to
2234 provide functionality specific to :class:`_expression.Select` and
2235 :class:`_selectable.CompoundSelect` while allowing
2236 :class:`_expression.SelectBase` to be
2237 used for other SELECT-like objects, e.g. :class:`.TextAsFrom`.
2238
2239 """
2240
2241 _order_by_clause = ClauseList()
2242 _group_by_clause = ClauseList()
2243 _limit_clause = None
2244 _offset_clause = None
2245 _for_update_arg = None
2246
2247 def __init__(
2248 self,
2249 use_labels=False,
2250 for_update=False,
2251 limit=None,
2252 offset=None,
2253 order_by=None,
2254 group_by=None,
2255 bind=None,
2256 autocommit=None,
2257 ):
2258 self.use_labels = use_labels
2259
2260 if for_update is not False:
2261 self._for_update_arg = ForUpdateArg.parse_legacy_select(for_update)
2262
2263 if autocommit is not None:
2264 util.warn_deprecated(
2265 "The select.autocommit parameter is deprecated and will be "
2266 "removed in a future release. Please refer to the "
2267 "Select.execution_options.autocommit` parameter."
2268 )
2269 self._execution_options = self._execution_options.union(
2270 {"autocommit": autocommit}
2271 )
2272 if limit is not None:
2273 self._limit_clause = _offset_or_limit_clause(limit)
2274 if offset is not None:
2275 self._offset_clause = _offset_or_limit_clause(offset)
2276 self._bind = bind
2277
2278 if order_by is not None:
2279 self._order_by_clause = ClauseList(
2280 *util.to_list(order_by),
2281 _literal_as_text=_literal_and_labels_as_label_reference
2282 )
2283 if group_by is not None:
2284 self._group_by_clause = ClauseList(
2285 *util.to_list(group_by),
2286 _literal_as_text=_literal_as_label_reference
2287 )
2288
2289 @property
2290 def for_update(self):
2291 """Provide legacy dialect support for the ``for_update`` attribute."""
2292 if self._for_update_arg is not None:
2293 return self._for_update_arg.legacy_for_update_value
2294 else:
2295 return None
2296
2297 @for_update.setter
2298 def for_update(self, value):
2299 self._for_update_arg = ForUpdateArg.parse_legacy_select(value)
2300
2301 @_generative
2302 def with_for_update(
2303 self,
2304 nowait=False,
2305 read=False,
2306 of=None,
2307 skip_locked=False,
2308 key_share=False,
2309 ):
2310 """Specify a ``FOR UPDATE`` clause for this
2311 :class:`_expression.GenerativeSelect`.
2312
2313 E.g.::
2314
2315 stmt = select([table]).with_for_update(nowait=True)
2316
2317 On a database like PostgreSQL or Oracle, the above would render a
2318 statement like::
2319
2320 SELECT table.a, table.b FROM table FOR UPDATE NOWAIT
2321
2322 on other backends, the ``nowait`` option is ignored and instead
2323 would produce::
2324
2325 SELECT table.a, table.b FROM table FOR UPDATE
2326
2327 When called with no arguments, the statement will render with
2328 the suffix ``FOR UPDATE``. Additional arguments can then be
2329 provided which allow for common database-specific
2330 variants.
2331
2332 :param nowait: boolean; will render ``FOR UPDATE NOWAIT`` on Oracle
2333 and PostgreSQL dialects.
2334
2335 :param read: boolean; will render ``LOCK IN SHARE MODE`` on MySQL,
2336 ``FOR SHARE`` on PostgreSQL. On PostgreSQL, when combined with
2337 ``nowait``, will render ``FOR SHARE NOWAIT``.
2338
2339 :param of: SQL expression or list of SQL expression elements
2340 (typically :class:`_schema.Column`
2341 objects or a compatible expression) which
2342 will render into a ``FOR UPDATE OF`` clause; supported by PostgreSQL
2343 and Oracle. May render as a table or as a column depending on
2344 backend.
2345
2346 :param skip_locked: boolean, will render ``FOR UPDATE SKIP LOCKED``
2347 on Oracle and PostgreSQL dialects or ``FOR SHARE SKIP LOCKED`` if
2348 ``read=True`` is also specified.
2349
2350 .. versionadded:: 1.1.0
2351
2352 :param key_share: boolean, will render ``FOR NO KEY UPDATE``,
2353 or if combined with ``read=True`` will render ``FOR KEY SHARE``,
2354 on the PostgreSQL dialect.
2355
2356 .. versionadded:: 1.1.0
2357
2358 """
2359 self._for_update_arg = ForUpdateArg(
2360 nowait=nowait,
2361 read=read,
2362 of=of,
2363 skip_locked=skip_locked,
2364 key_share=key_share,
2365 )
2366
2367 @_generative
2368 def apply_labels(self):
2369 """Return a new selectable with the 'use_labels' flag set to True.
2370
2371 This will result in column expressions being generated using labels
2372 against their table name, such as "SELECT somecolumn AS
2373 tablename_somecolumn". This allows selectables which contain multiple
2374 FROM clauses to produce a unique set of column names regardless of
2375 name conflicts among the individual FROM clauses.
2376
2377 """
2378 self.use_labels = True
2379
2380 @property
2381 def _limit(self):
2382 """Get an integer value for the limit. This should only be used
2383 by code that cannot support a limit as a BindParameter or
2384 other custom clause as it will throw an exception if the limit
2385 isn't currently set to an integer.
2386
2387 """
2388 return _offset_or_limit_clause_asint(self._limit_clause, "limit")
2389
2390 @property
2391 def _simple_int_limit(self):
2392 """True if the LIMIT clause is a simple integer, False
2393 if it is not present or is a SQL expression.
2394 """
2395 return isinstance(self._limit_clause, _OffsetLimitParam)
2396
2397 @property
2398 def _simple_int_offset(self):
2399 """True if the OFFSET clause is a simple integer, False
2400 if it is not present or is a SQL expression.
2401 """
2402 return isinstance(self._offset_clause, _OffsetLimitParam)
2403
2404 @property
2405 def _offset(self):
2406 """Get an integer value for the offset. This should only be used
2407 by code that cannot support an offset as a BindParameter or
2408 other custom clause as it will throw an exception if the
2409 offset isn't currently set to an integer.
2410
2411 """
2412 return _offset_or_limit_clause_asint(self._offset_clause, "offset")
2413
2414 @_generative
2415 def limit(self, limit):
2416 """Return a new selectable with the given LIMIT criterion
2417 applied.
2418
2419 This is a numerical value which usually renders as a ``LIMIT``
2420 expression in the resulting select. Backends that don't
2421 support ``LIMIT`` will attempt to provide similar
2422 functionality.
2423
2424 .. versionchanged:: 1.0.0 - :meth:`_expression.Select.limit` can now
2425 accept arbitrary SQL expressions as well as integer values.
2426
2427 :param limit: an integer LIMIT parameter, or a SQL expression
2428 that provides an integer result.
2429
2430 """
2431
2432 self._limit_clause = _offset_or_limit_clause(limit)
2433
2434 @_generative
2435 def offset(self, offset):
2436 """Return a new selectable with the given OFFSET criterion
2437 applied.
2438
2439
2440 This is a numeric value which usually renders as an ``OFFSET``
2441 expression in the resulting select. Backends that don't
2442 support ``OFFSET`` will attempt to provide similar
2443 functionality.
2444
2445
2446 .. versionchanged:: 1.0.0 - :meth:`_expression.Select.offset` can now
2447 accept arbitrary SQL expressions as well as integer values.
2448
2449 :param offset: an integer OFFSET parameter, or a SQL expression
2450 that provides an integer result.
2451
2452 """
2453
2454 self._offset_clause = _offset_or_limit_clause(offset)
2455
2456 @_generative
2457 def order_by(self, *clauses):
2458 r"""Return a new selectable with the given list of ORDER BY
2459 criterion applied.
2460
2461 e.g.::
2462
2463 stmt = select([table]).order_by(table.c.id, table.c.name)
2464
2465 :param \*clauses: a series of :class:`_expression.ColumnElement`
2466 constructs
2467 which will be used to generate an ORDER BY clause.
2468
2469 .. seealso::
2470
2471 :ref:`core_tutorial_ordering`
2472
2473 """
2474
2475 self.append_order_by(*clauses)
2476
2477 @_generative
2478 def group_by(self, *clauses):
2479 r"""Return a new selectable with the given list of GROUP BY
2480 criterion applied.
2481
2482 e.g.::
2483
2484 stmt = select([table.c.name, func.max(table.c.stat)]).\
2485 group_by(table.c.name)
2486
2487 :param \*clauses: a series of :class:`_expression.ColumnElement`
2488 constructs
2489 which will be used to generate an GROUP BY clause.
2490
2491 .. seealso::
2492
2493 :ref:`core_tutorial_ordering`
2494
2495 """
2496
2497 self.append_group_by(*clauses)
2498
2499 def append_order_by(self, *clauses):
2500 """Append the given ORDER BY criterion applied to this selectable.
2501
2502 The criterion will be appended to any pre-existing ORDER BY criterion.
2503
2504 This is an **in-place** mutation method; the
2505 :meth:`_expression.GenerativeSelect.order_by` method is preferred,
2506 as it
2507 provides standard :term:`method chaining`.
2508
2509 .. seealso::
2510
2511 :meth:`_expression.GenerativeSelect.order_by`
2512
2513 """
2514 if len(clauses) == 1 and clauses[0] is None:
2515 self._order_by_clause = ClauseList()
2516 else:
2517 if getattr(self, "_order_by_clause", None) is not None:
2518 clauses = list(self._order_by_clause) + list(clauses)
2519 self._order_by_clause = ClauseList(
2520 *clauses,
2521 _literal_as_text=_literal_and_labels_as_label_reference
2522 )
2523
2524 def append_group_by(self, *clauses):
2525 """Append the given GROUP BY criterion applied to this selectable.
2526
2527 The criterion will be appended to any pre-existing GROUP BY criterion.
2528
2529 This is an **in-place** mutation method; the
2530 :meth:`_expression.GenerativeSelect.group_by` method is preferred,
2531 as it provides standard :term:`method chaining`.
2532
2533 .. seealso::
2534
2535 :meth:`_expression.GenerativeSelect.group_by`
2536
2537 """
2538 if len(clauses) == 1 and clauses[0] is None:
2539 self._group_by_clause = ClauseList()
2540 else:
2541 if getattr(self, "_group_by_clause", None) is not None:
2542 clauses = list(self._group_by_clause) + list(clauses)
2543 self._group_by_clause = ClauseList(
2544 *clauses, _literal_as_text=_literal_as_label_reference
2545 )
2546
2547 @property
2548 def _label_resolve_dict(self):
2549 raise NotImplementedError()
2550
2551 def _copy_internals(self, clone=_clone, **kw):
2552 if self._limit_clause is not None:
2553 self._limit_clause = clone(self._limit_clause, **kw)
2554 if self._offset_clause is not None:
2555 self._offset_clause = clone(self._offset_clause, **kw)
2556
2557
2558class CompoundSelect(GenerativeSelect):
2559 """Forms the basis of ``UNION``, ``UNION ALL``, and other
2560 SELECT-based set operations.
2561
2562
2563 .. seealso::
2564
2565 :func:`_expression.union`
2566
2567 :func:`_expression.union_all`
2568
2569 :func:`_expression.intersect`
2570
2571 :func:`_expression.intersect_all`
2572
2573 :func:`_expression.except`
2574
2575 :func:`_expression.except_all`
2576
2577 """
2578
2579 __visit_name__ = "compound_select"
2580
2581 UNION = util.symbol("UNION")
2582 UNION_ALL = util.symbol("UNION ALL")
2583 EXCEPT = util.symbol("EXCEPT")
2584 EXCEPT_ALL = util.symbol("EXCEPT ALL")
2585 INTERSECT = util.symbol("INTERSECT")
2586 INTERSECT_ALL = util.symbol("INTERSECT ALL")
2587
2588 _is_from_container = True
2589
2590 def __init__(self, keyword, *selects, **kwargs):
2591 self._auto_correlate = kwargs.pop("correlate", False)
2592 self.keyword = keyword
2593 self.selects = []
2594
2595 numcols = None
2596
2597 # some DBs do not like ORDER BY in the inner queries of a UNION, etc.
2598 for n, s in enumerate(selects):
2599 s = _clause_element_as_expr(s)
2600
2601 if not numcols:
2602 numcols = len(s.c._all_columns)
2603 elif len(s.c._all_columns) != numcols:
2604 raise exc.ArgumentError(
2605 "All selectables passed to "
2606 "CompoundSelect must have identical numbers of "
2607 "columns; select #%d has %d columns, select "
2608 "#%d has %d"
2609 % (
2610 1,
2611 len(self.selects[0].c._all_columns),
2612 n + 1,
2613 len(s.c._all_columns),
2614 )
2615 )
2616
2617 self.selects.append(s.self_group(against=self))
2618
2619 GenerativeSelect.__init__(self, **kwargs)
2620
2621 @property
2622 def _label_resolve_dict(self):
2623 d = dict((c.key, c) for c in self.c)
2624 return d, d, d
2625
2626 @classmethod
2627 def _create_union(cls, *selects, **kwargs):
2628 r"""Return a ``UNION`` of multiple selectables.
2629
2630 The returned object is an instance of
2631 :class:`_selectable.CompoundSelect`.
2632
2633 A similar :func:`union()` method is available on all
2634 :class:`_expression.FromClause` subclasses.
2635
2636 :param \*selects:
2637 a list of :class:`_expression.Select` instances.
2638
2639 :param \**kwargs:
2640 available keyword arguments are the same as those of
2641 :func:`select`.
2642
2643 """
2644 return CompoundSelect(CompoundSelect.UNION, *selects, **kwargs)
2645
2646 @classmethod
2647 def _create_union_all(cls, *selects, **kwargs):
2648 r"""Return a ``UNION ALL`` of multiple selectables.
2649
2650 The returned object is an instance of
2651 :class:`_selectable.CompoundSelect`.
2652
2653 A similar :func:`union_all()` method is available on all
2654 :class:`_expression.FromClause` subclasses.
2655
2656 :param \*selects:
2657 a list of :class:`_expression.Select` instances.
2658
2659 :param \**kwargs:
2660 available keyword arguments are the same as those of
2661 :func:`select`.
2662
2663 """
2664 return CompoundSelect(CompoundSelect.UNION_ALL, *selects, **kwargs)
2665
2666 @classmethod
2667 def _create_except(cls, *selects, **kwargs):
2668 r"""Return an ``EXCEPT`` of multiple selectables.
2669
2670 The returned object is an instance of
2671 :class:`_selectable.CompoundSelect`.
2672
2673 :param \*selects:
2674 a list of :class:`_expression.Select` instances.
2675
2676 :param \**kwargs:
2677 available keyword arguments are the same as those of
2678 :func:`select`.
2679
2680 """
2681 return CompoundSelect(CompoundSelect.EXCEPT, *selects, **kwargs)
2682
2683 @classmethod
2684 def _create_except_all(cls, *selects, **kwargs):
2685 r"""Return an ``EXCEPT ALL`` of multiple selectables.
2686
2687 The returned object is an instance of
2688 :class:`_selectable.CompoundSelect`.
2689
2690 :param \*selects:
2691 a list of :class:`_expression.Select` instances.
2692
2693 :param \**kwargs:
2694 available keyword arguments are the same as those of
2695 :func:`select`.
2696
2697 """
2698 return CompoundSelect(CompoundSelect.EXCEPT_ALL, *selects, **kwargs)
2699
2700 @classmethod
2701 def _create_intersect(cls, *selects, **kwargs):
2702 r"""Return an ``INTERSECT`` of multiple selectables.
2703
2704 The returned object is an instance of
2705 :class:`_selectable.CompoundSelect`.
2706
2707 :param \*selects:
2708 a list of :class:`_expression.Select` instances.
2709
2710 :param \**kwargs:
2711 available keyword arguments are the same as those of
2712 :func:`select`.
2713
2714 """
2715 return CompoundSelect(CompoundSelect.INTERSECT, *selects, **kwargs)
2716
2717 @classmethod
2718 def _create_intersect_all(cls, *selects, **kwargs):
2719 r"""Return an ``INTERSECT ALL`` of multiple selectables.
2720
2721 The returned object is an instance of
2722 :class:`_selectable.CompoundSelect`.
2723
2724 :param \*selects:
2725 a list of :class:`_expression.Select` instances.
2726
2727 :param \**kwargs:
2728 available keyword arguments are the same as those of
2729 :func:`select`.
2730
2731 """
2732 return CompoundSelect(CompoundSelect.INTERSECT_ALL, *selects, **kwargs)
2733
2734 def _scalar_type(self):
2735 return self.selects[0]._scalar_type()
2736
2737 def self_group(self, against=None):
2738 return FromGrouping(self)
2739
2740 def is_derived_from(self, fromclause):
2741 for s in self.selects:
2742 if s.is_derived_from(fromclause):
2743 return True
2744 return False
2745
2746 def _populate_column_collection(self):
2747 for cols in zip(*[s.c._all_columns for s in self.selects]):
2748
2749 # this is a slightly hacky thing - the union exports a
2750 # column that resembles just that of the *first* selectable.
2751 # to get at a "composite" column, particularly foreign keys,
2752 # you have to dig through the proxies collection which we
2753 # generate below. We may want to improve upon this, such as
2754 # perhaps _make_proxy can accept a list of other columns
2755 # that are "shared" - schema.column can then copy all the
2756 # ForeignKeys in. this would allow the union() to have all
2757 # those fks too.
2758
2759 proxy = cols[0]._make_proxy(
2760 self,
2761 name=cols[0]._label if self.use_labels else None,
2762 key=cols[0]._key_label if self.use_labels else None,
2763 )
2764
2765 # hand-construct the "_proxies" collection to include all
2766 # derived columns place a 'weight' annotation corresponding
2767 # to how low in the list of select()s the column occurs, so
2768 # that the corresponding_column() operation can resolve
2769 # conflicts
2770 proxy._proxies = [
2771 c._annotate({"weight": i + 1}) for (i, c) in enumerate(cols)
2772 ]
2773
2774 def _refresh_for_new_column(self, column):
2775 for s in self.selects:
2776 s._refresh_for_new_column(column)
2777
2778 if not self._cols_populated:
2779 return None
2780
2781 raise NotImplementedError(
2782 "CompoundSelect constructs don't support "
2783 "addition of columns to underlying "
2784 "selectables"
2785 )
2786
2787 def _copy_internals(self, clone=_clone, **kw):
2788 super(CompoundSelect, self)._copy_internals(clone, **kw)
2789 self._reset_exported()
2790 self.selects = [clone(s, **kw) for s in self.selects]
2791 if hasattr(self, "_col_map"):
2792 del self._col_map
2793 for attr in (
2794 "_order_by_clause",
2795 "_group_by_clause",
2796 "_for_update_arg",
2797 ):
2798 if getattr(self, attr) is not None:
2799 setattr(self, attr, clone(getattr(self, attr), **kw))
2800
2801 def get_children(self, column_collections=True, **kwargs):
2802 return (
2803 (column_collections and list(self.c) or [])
2804 + [self._order_by_clause, self._group_by_clause]
2805 + list(self.selects)
2806 )
2807
2808 def bind(self):
2809 if self._bind:
2810 return self._bind
2811 for s in self.selects:
2812 e = s.bind
2813 if e:
2814 return e
2815 else:
2816 return None
2817
2818 def _set_bind(self, bind):
2819 self._bind = bind
2820
2821 bind = property(bind, _set_bind)
2822
2823
2824class Select(HasPrefixes, HasSuffixes, GenerativeSelect):
2825 """Represents a ``SELECT`` statement."""
2826
2827 __visit_name__ = "select"
2828
2829 _prefixes = ()
2830 _suffixes = ()
2831 _hints = util.immutabledict()
2832 _statement_hints = ()
2833 _distinct = False
2834 _from_cloned = None
2835 _correlate = ()
2836 _correlate_except = None
2837 _memoized_property = SelectBase._memoized_property
2838 _is_select = True
2839
2840 @util.deprecated_params(
2841 autocommit=(
2842 "0.6",
2843 "The :paramref:`_expression.select.autocommit` "
2844 "parameter is deprecated "
2845 "and will be removed in a future release. Please refer to "
2846 "the :paramref:`.Connection.execution_options.autocommit` "
2847 "parameter in conjunction with the the "
2848 ":meth:`.Executable.execution_options` method in order to "
2849 "affect the autocommit behavior for a statement.",
2850 ),
2851 for_update=(
2852 "0.9",
2853 "The :paramref:`_expression.select.for_update` "
2854 "parameter is deprecated and "
2855 "will be removed in a future release. Please refer to the "
2856 ":meth:`_expression.Select.with_for_update` to specify the "
2857 "structure of the ``FOR UPDATE`` clause.",
2858 ),
2859 )
2860 def __init__(
2861 self,
2862 columns=None,
2863 whereclause=None,
2864 from_obj=None,
2865 distinct=False,
2866 having=None,
2867 correlate=True,
2868 prefixes=None,
2869 suffixes=None,
2870 **kwargs
2871 ):
2872 """Construct a new :class:`_expression.Select`.
2873
2874 Similar functionality is also available via the
2875 :meth:`_expression.FromClause.select` method on any
2876 :class:`_expression.FromClause`.
2877
2878 All arguments which accept :class:`_expression.ClauseElement`
2879 arguments also
2880 accept string arguments, which will be converted as appropriate into
2881 either :func:`_expression.text` or
2882 :func:`_expression.literal_column` constructs.
2883
2884 .. seealso::
2885
2886 :ref:`coretutorial_selecting` - Core Tutorial description of
2887 :func:`_expression.select`.
2888
2889 :param columns:
2890 A list of :class:`_expression.ColumnElement` or
2891 :class:`_expression.FromClause`
2892 objects which will form the columns clause of the resulting
2893 statement. For those objects that are instances of
2894 :class:`_expression.FromClause` (typically :class:`_schema.Table`
2895 or :class:`_expression.Alias`
2896 objects), the :attr:`_expression.FromClause.c`
2897 collection is extracted
2898 to form a collection of :class:`_expression.ColumnElement` objects.
2899
2900 This parameter will also accept :class:`_expression.TextClause`
2901 constructs as
2902 given, as well as ORM-mapped classes.
2903
2904 .. note::
2905
2906 The :paramref:`_expression.select.columns`
2907 parameter is not available
2908 in the method form of :func:`_expression.select`, e.g.
2909 :meth:`_expression.FromClause.select`.
2910
2911 .. seealso::
2912
2913 :meth:`_expression.Select.column`
2914
2915 :meth:`_expression.Select.with_only_columns`
2916
2917 :param whereclause:
2918 A :class:`_expression.ClauseElement`
2919 expression which will be used to form the
2920 ``WHERE`` clause. It is typically preferable to add WHERE
2921 criterion to an existing :class:`_expression.Select`
2922 using method chaining
2923 with :meth:`_expression.Select.where`.
2924
2925 .. seealso::
2926
2927 :meth:`_expression.Select.where`
2928
2929 :param from_obj:
2930 A list of :class:`_expression.ClauseElement`
2931 objects which will be added to the
2932 ``FROM`` clause of the resulting statement. This is equivalent
2933 to calling :meth:`_expression.Select.select_from`
2934 using method chaining on
2935 an existing :class:`_expression.Select` object.
2936
2937 .. seealso::
2938
2939 :meth:`_expression.Select.select_from`
2940 - full description of explicit
2941 FROM clause specification.
2942
2943 :param autocommit: legacy autocommit parameter.
2944
2945 :param bind=None:
2946 an :class:`_engine.Engine` or :class:`_engine.Connection` instance
2947 to which the
2948 resulting :class:`_expression.Select` object will be bound. The
2949 :class:`_expression.Select`
2950 object will otherwise automatically bind to
2951 whatever :class:`~.base.Connectable` instances can be located within
2952 its contained :class:`_expression.ClauseElement` members.
2953
2954 :param correlate=True:
2955 indicates that this :class:`_expression.Select`
2956 object should have its
2957 contained :class:`_expression.FromClause`
2958 elements "correlated" to an enclosing
2959 :class:`_expression.Select` object.
2960 It is typically preferable to specify
2961 correlations on an existing :class:`_expression.Select`
2962 construct using
2963 :meth:`_expression.Select.correlate`.
2964
2965 .. seealso::
2966
2967 :meth:`_expression.Select.correlate`
2968 - full description of correlation.
2969
2970 :param distinct=False:
2971 when ``True``, applies a ``DISTINCT`` qualifier to the columns
2972 clause of the resulting statement.
2973
2974 The boolean argument may also be a column expression or list
2975 of column expressions - this is a special calling form which
2976 is understood by the PostgreSQL dialect to render the
2977 ``DISTINCT ON (<columns>)`` syntax.
2978
2979 ``distinct`` is also available on an existing
2980 :class:`_expression.Select`
2981 object via the :meth:`_expression.Select.distinct` method.
2982
2983 .. seealso::
2984
2985 :meth:`_expression.Select.distinct`
2986
2987 :param for_update=False:
2988 when ``True``, applies ``FOR UPDATE`` to the end of the
2989 resulting statement.
2990
2991 ``for_update`` accepts various string values interpreted by
2992 specific backends, including:
2993
2994 * ``"read"`` - on MySQL, translates to ``LOCK IN SHARE MODE``;
2995 on PostgreSQL, translates to ``FOR SHARE``.
2996 * ``"nowait"`` - on PostgreSQL and Oracle, translates to
2997 ``FOR UPDATE NOWAIT``.
2998 * ``"read_nowait"`` - on PostgreSQL, translates to
2999 ``FOR SHARE NOWAIT``.
3000
3001 .. seealso::
3002
3003 :meth:`_expression.Select.with_for_update` - improved API for
3004 specifying the ``FOR UPDATE`` clause.
3005
3006 :param group_by:
3007 a list of :class:`_expression.ClauseElement`
3008 objects which will comprise the
3009 ``GROUP BY`` clause of the resulting select. This parameter
3010 is typically specified more naturally using the
3011 :meth:`_expression.Select.group_by` method on an existing
3012 :class:`_expression.Select`.
3013
3014 .. seealso::
3015
3016 :meth:`_expression.Select.group_by`
3017
3018 :param having:
3019 a :class:`_expression.ClauseElement`
3020 that will comprise the ``HAVING`` clause
3021 of the resulting select when ``GROUP BY`` is used. This parameter
3022 is typically specified more naturally using the
3023 :meth:`_expression.Select.having` method on an existing
3024 :class:`_expression.Select`.
3025
3026 .. seealso::
3027
3028 :meth:`_expression.Select.having`
3029
3030 :param limit=None:
3031 a numerical value which usually renders as a ``LIMIT``
3032 expression in the resulting select. Backends that don't
3033 support ``LIMIT`` will attempt to provide similar
3034 functionality. This parameter is typically specified more
3035 naturally using the :meth:`_expression.Select.limit`
3036 method on an existing
3037 :class:`_expression.Select`.
3038
3039 .. seealso::
3040
3041 :meth:`_expression.Select.limit`
3042
3043 :param offset=None:
3044 a numeric value which usually renders as an ``OFFSET``
3045 expression in the resulting select. Backends that don't
3046 support ``OFFSET`` will attempt to provide similar
3047 functionality. This parameter is typically specified more naturally
3048 using the :meth:`_expression.Select.offset` method on an existing
3049 :class:`_expression.Select`.
3050
3051 .. seealso::
3052
3053 :meth:`_expression.Select.offset`
3054
3055 :param order_by:
3056 a scalar or list of :class:`_expression.ClauseElement`
3057 objects which will
3058 comprise the ``ORDER BY`` clause of the resulting select.
3059 This parameter is typically specified more naturally using the
3060 :meth:`_expression.Select.order_by` method on an existing
3061 :class:`_expression.Select`.
3062
3063 .. seealso::
3064
3065 :meth:`_expression.Select.order_by`
3066
3067 :param use_labels=False:
3068 when ``True``, the statement will be generated using labels
3069 for each column in the columns clause, which qualify each
3070 column with its parent table's (or aliases) name so that name
3071 conflicts between columns in different tables don't occur.
3072 The format of the label is ``<tablename>_<column>``. The "c"
3073 collection of the resulting :class:`_expression.Select`
3074 object will use these
3075 names as well for targeting column members.
3076
3077 This parameter can also be specified on an existing
3078 :class:`_expression.Select` object using the
3079 :meth:`_expression.Select.apply_labels`
3080 method.
3081
3082 .. seealso::
3083
3084 :meth:`_expression.Select.apply_labels`
3085
3086 """
3087 self._auto_correlate = correlate
3088 if distinct is not False:
3089 if distinct is True:
3090 self._distinct = True
3091 else:
3092 self._distinct = [
3093 _literal_as_label_reference(e)
3094 for e in util.to_list(distinct)
3095 ]
3096
3097 if from_obj is not None:
3098 self._from_obj = util.OrderedSet(
3099 _interpret_as_from(f) for f in util.to_list(from_obj)
3100 )
3101 else:
3102 self._from_obj = util.OrderedSet()
3103
3104 try:
3105 cols_present = bool(columns)
3106 except TypeError as err:
3107 util.raise_(
3108 exc.ArgumentError(
3109 "columns argument to select() must "
3110 "be a Python list or other iterable"
3111 ),
3112 replace_context=err,
3113 )
3114
3115 if cols_present:
3116 self._raw_columns = []
3117 for c in columns:
3118 c = _interpret_as_column_or_from(c)
3119 if isinstance(c, ScalarSelect):
3120 c = c.self_group(against=operators.comma_op)
3121 self._raw_columns.append(c)
3122 else:
3123 self._raw_columns = []
3124
3125 if whereclause is not None:
3126 self._whereclause = _literal_as_text(whereclause).self_group(
3127 against=operators._asbool
3128 )
3129 else:
3130 self._whereclause = None
3131
3132 if having is not None:
3133 self._having = _literal_as_text(having).self_group(
3134 against=operators._asbool
3135 )
3136 else:
3137 self._having = None
3138
3139 if prefixes:
3140 self._setup_prefixes(prefixes)
3141
3142 if suffixes:
3143 self._setup_suffixes(suffixes)
3144
3145 GenerativeSelect.__init__(self, **kwargs)
3146
3147 @property
3148 def _froms(self):
3149 # would love to cache this,
3150 # but there's just enough edge cases, particularly now that
3151 # declarative encourages construction of SQL expressions
3152 # without tables present, to just regen this each time.
3153 froms = []
3154 seen = set()
3155 translate = self._from_cloned
3156
3157 for item in itertools.chain(
3158 _from_objects(*self._raw_columns),
3159 _from_objects(self._whereclause)
3160 if self._whereclause is not None
3161 else (),
3162 self._from_obj,
3163 ):
3164 if item is self:
3165 raise exc.InvalidRequestError(
3166 "select() construct refers to itself as a FROM"
3167 )
3168 if translate and item in translate:
3169 item = translate[item]
3170 if not seen.intersection(item._cloned_set):
3171 froms.append(item)
3172 seen.update(item._cloned_set)
3173
3174 return froms
3175
3176 def _get_display_froms(
3177 self, explicit_correlate_froms=None, implicit_correlate_froms=None
3178 ):
3179 """Return the full list of 'from' clauses to be displayed.
3180
3181 Takes into account a set of existing froms which may be
3182 rendered in the FROM clause of enclosing selects; this Select
3183 may want to leave those absent if it is automatically
3184 correlating.
3185
3186 """
3187 froms = self._froms
3188
3189 toremove = set(
3190 itertools.chain(*[_expand_cloned(f._hide_froms) for f in froms])
3191 )
3192 if toremove:
3193 # if we're maintaining clones of froms,
3194 # add the copies out to the toremove list. only include
3195 # clones that are lexical equivalents.
3196 if self._from_cloned:
3197 toremove.update(
3198 self._from_cloned[f]
3199 for f in toremove.intersection(self._from_cloned)
3200 if self._from_cloned[f]._is_lexical_equivalent(f)
3201 )
3202 # filter out to FROM clauses not in the list,
3203 # using a list to maintain ordering
3204 froms = [f for f in froms if f not in toremove]
3205
3206 if self._correlate:
3207 to_correlate = self._correlate
3208 if to_correlate:
3209 froms = [
3210 f
3211 for f in froms
3212 if f
3213 not in _cloned_intersection(
3214 _cloned_intersection(
3215 froms, explicit_correlate_froms or ()
3216 ),
3217 to_correlate,
3218 )
3219 ]
3220
3221 if self._correlate_except is not None:
3222
3223 froms = [
3224 f
3225 for f in froms
3226 if f
3227 not in _cloned_difference(
3228 _cloned_intersection(
3229 froms, explicit_correlate_froms or ()
3230 ),
3231 self._correlate_except,
3232 )
3233 ]
3234
3235 if (
3236 self._auto_correlate
3237 and implicit_correlate_froms
3238 and len(froms) > 1
3239 ):
3240
3241 froms = [
3242 f
3243 for f in froms
3244 if f
3245 not in _cloned_intersection(froms, implicit_correlate_froms)
3246 ]
3247
3248 if not len(froms):
3249 raise exc.InvalidRequestError(
3250 "Select statement '%s"
3251 "' returned no FROM clauses "
3252 "due to auto-correlation; "
3253 "specify correlate(<tables>) "
3254 "to control correlation "
3255 "manually." % self
3256 )
3257
3258 return froms
3259
3260 def _scalar_type(self):
3261 elem = self._raw_columns[0]
3262 cols = list(elem._select_iterable)
3263 return cols[0].type
3264
3265 @property
3266 def froms(self):
3267 """Return the displayed list of FromClause elements."""
3268
3269 return self._get_display_froms()
3270
3271 def with_statement_hint(self, text, dialect_name="*"):
3272 """Add a statement hint to this :class:`_expression.Select`.
3273
3274 This method is similar to :meth:`_expression.Select.with_hint`
3275 except that
3276 it does not require an individual table, and instead applies to the
3277 statement as a whole.
3278
3279 Hints here are specific to the backend database and may include
3280 directives such as isolation levels, file directives, fetch directives,
3281 etc.
3282
3283 .. versionadded:: 1.0.0
3284
3285 .. seealso::
3286
3287 :meth:`_expression.Select.with_hint`
3288
3289 :meth:`.Select.prefix_with` - generic SELECT prefixing which also
3290 can suit some database-specific HINT syntaxes such as MySQL
3291 optimizer hints
3292
3293 """
3294 return self.with_hint(None, text, dialect_name)
3295
3296 @_generative
3297 def with_hint(self, selectable, text, dialect_name="*"):
3298 r"""Add an indexing or other executional context hint for the given
3299 selectable to this :class:`_expression.Select`.
3300
3301 The text of the hint is rendered in the appropriate
3302 location for the database backend in use, relative
3303 to the given :class:`_schema.Table` or :class:`_expression.Alias`
3304 passed as the
3305 ``selectable`` argument. The dialect implementation
3306 typically uses Python string substitution syntax
3307 with the token ``%(name)s`` to render the name of
3308 the table or alias. E.g. when using Oracle, the
3309 following::
3310
3311 select([mytable]).\
3312 with_hint(mytable, "index(%(name)s ix_mytable)")
3313
3314 Would render SQL as::
3315
3316 select /*+ index(mytable ix_mytable) */ ... from mytable
3317
3318 The ``dialect_name`` option will limit the rendering of a particular
3319 hint to a particular backend. Such as, to add hints for both Oracle
3320 and Sybase simultaneously::
3321
3322 select([mytable]).\
3323 with_hint(mytable, "index(%(name)s ix_mytable)", 'oracle').\
3324 with_hint(mytable, "WITH INDEX ix_mytable", 'sybase')
3325
3326 .. seealso::
3327
3328 :meth:`_expression.Select.with_statement_hint`
3329
3330 """
3331 if selectable is None:
3332 self._statement_hints += ((dialect_name, text),)
3333 else:
3334 self._hints = self._hints.union({(selectable, dialect_name): text})
3335
3336 @property
3337 def type(self):
3338 raise exc.InvalidRequestError(
3339 "Select objects don't have a type. "
3340 "Call as_scalar() on this Select "
3341 "object to return a 'scalar' version "
3342 "of this Select."
3343 )
3344
3345 @_memoized_property.method
3346 def locate_all_froms(self):
3347 """Return a Set of all :class:`_expression.FromClause` elements
3348 referenced by this Select.
3349
3350 This set is a superset of that returned by the ``froms`` property,
3351 which is specifically for those FromClause elements that would
3352 actually be rendered.
3353
3354 """
3355 froms = self._froms
3356 return froms + list(_from_objects(*froms))
3357
3358 @property
3359 def inner_columns(self):
3360 """An iterator of all :class:`_expression.ColumnElement`
3361 expressions which would
3362 be rendered into the columns clause of the resulting SELECT statement.
3363
3364 """
3365 return _select_iterables(self._raw_columns)
3366
3367 @_memoized_property
3368 def _label_resolve_dict(self):
3369 with_cols = dict(
3370 (c._resolve_label or c._label or c.key, c)
3371 for c in _select_iterables(self._raw_columns)
3372 if c._allow_label_resolve
3373 )
3374 only_froms = dict(
3375 (c.key, c)
3376 for c in _select_iterables(self.froms)
3377 if c._allow_label_resolve
3378 )
3379 only_cols = with_cols.copy()
3380 for key, value in only_froms.items():
3381 with_cols.setdefault(key, value)
3382
3383 return with_cols, only_froms, only_cols
3384
3385 def is_derived_from(self, fromclause):
3386 if self in fromclause._cloned_set:
3387 return True
3388
3389 for f in self.locate_all_froms():
3390 if f.is_derived_from(fromclause):
3391 return True
3392 return False
3393
3394 def _copy_internals(self, clone=_clone, **kw):
3395 super(Select, self)._copy_internals(clone, **kw)
3396
3397 # Select() object has been cloned and probably adapted by the
3398 # given clone function. Apply the cloning function to internal
3399 # objects
3400
3401 # 1. keep a dictionary of the froms we've cloned, and what
3402 # they've become. This is consulted later when we derive
3403 # additional froms from "whereclause" and the columns clause,
3404 # which may still reference the uncloned parent table.
3405 # as of 0.7.4 we also put the current version of _froms, which
3406 # gets cleared on each generation. previously we were "baking"
3407 # _froms into self._from_obj.
3408 self._from_cloned = from_cloned = dict(
3409 (f, clone(f, **kw)) for f in self._from_obj.union(self._froms)
3410 )
3411
3412 # 3. update persistent _from_obj with the cloned versions.
3413 self._from_obj = util.OrderedSet(
3414 from_cloned[f] for f in self._from_obj
3415 )
3416
3417 # the _correlate collection is done separately, what can happen
3418 # here is the same item is _correlate as in _from_obj but the
3419 # _correlate version has an annotation on it - (specifically
3420 # RelationshipProperty.Comparator._criterion_exists() does
3421 # this). Also keep _correlate liberally open with its previous
3422 # contents, as this set is used for matching, not rendering.
3423 self._correlate = set(clone(f, **kw) for f in self._correlate).union(
3424 self._correlate
3425 )
3426
3427 # do something similar for _correlate_except - this is a more
3428 # unusual case but same idea applies
3429 if self._correlate_except:
3430 self._correlate_except = set(
3431 clone(f, **kw) for f in self._correlate_except
3432 ).union(self._correlate_except)
3433
3434 # 4. clone other things. The difficulty here is that Column
3435 # objects are not actually cloned, and refer to their original
3436 # .table, resulting in the wrong "from" parent after a clone
3437 # operation. Hence _from_cloned and _from_obj supersede what is
3438 # present here.
3439 self._raw_columns = [clone(c, **kw) for c in self._raw_columns]
3440 for attr in (
3441 "_whereclause",
3442 "_having",
3443 "_order_by_clause",
3444 "_group_by_clause",
3445 "_for_update_arg",
3446 ):
3447 if getattr(self, attr) is not None:
3448 setattr(self, attr, clone(getattr(self, attr), **kw))
3449
3450 # erase exported column list, _froms collection,
3451 # etc.
3452 self._reset_exported()
3453
3454 def get_children(self, column_collections=True, **kwargs):
3455 """Return child elements as per the ClauseElement specification."""
3456
3457 return (
3458 (column_collections and list(self.columns) or [])
3459 + self._raw_columns
3460 + list(self._froms)
3461 + [
3462 x
3463 for x in (
3464 self._whereclause,
3465 self._having,
3466 self._order_by_clause,
3467 self._group_by_clause,
3468 )
3469 if x is not None
3470 ]
3471 )
3472
3473 @_generative
3474 def column(self, column):
3475 """Return a new :func:`_expression.select` construct with
3476 the given column expression added to its columns clause.
3477
3478 E.g.::
3479
3480 my_select = my_select.column(table.c.new_column)
3481
3482 See the documentation for
3483 :meth:`_expression.Select.with_only_columns`
3484 for guidelines on adding /replacing the columns of a
3485 :class:`_expression.Select` object.
3486
3487 """
3488 self.append_column(column)
3489
3490 @util.dependencies("sqlalchemy.sql.util")
3491 def reduce_columns(self, sqlutil, only_synonyms=True):
3492 """Return a new :func:`_expression.select` construct with redundantly
3493 named, equivalently-valued columns removed from the columns clause.
3494
3495 "Redundant" here means two columns where one refers to the
3496 other either based on foreign key, or via a simple equality
3497 comparison in the WHERE clause of the statement. The primary purpose
3498 of this method is to automatically construct a select statement
3499 with all uniquely-named columns, without the need to use
3500 table-qualified labels as :meth:`_expression.Select.apply_labels`
3501 does.
3502
3503 When columns are omitted based on foreign key, the referred-to
3504 column is the one that's kept. When columns are omitted based on
3505 WHERE equivalence, the first column in the columns clause is the
3506 one that's kept.
3507
3508 :param only_synonyms: when True, limit the removal of columns
3509 to those which have the same name as the equivalent. Otherwise,
3510 all columns that are equivalent to another are removed.
3511
3512 """
3513 return self.with_only_columns(
3514 sqlutil.reduce_columns(
3515 self.inner_columns,
3516 only_synonyms=only_synonyms,
3517 *(self._whereclause,) + tuple(self._from_obj)
3518 )
3519 )
3520
3521 @_generative
3522 def with_only_columns(self, columns):
3523 r"""Return a new :func:`_expression.select` construct with its columns
3524 clause replaced with the given columns.
3525
3526 This method is exactly equivalent to as if the original
3527 :func:`_expression.select` had been called with the given columns
3528 clause. I.e. a statement::
3529
3530 s = select([table1.c.a, table1.c.b])
3531 s = s.with_only_columns([table1.c.b])
3532
3533 should be exactly equivalent to::
3534
3535 s = select([table1.c.b])
3536
3537 This means that FROM clauses which are only derived
3538 from the column list will be discarded if the new column
3539 list no longer contains that FROM::
3540
3541 >>> table1 = table('t1', column('a'), column('b'))
3542 >>> table2 = table('t2', column('a'), column('b'))
3543 >>> s1 = select([table1.c.a, table2.c.b])
3544 >>> print(s1)
3545 SELECT t1.a, t2.b FROM t1, t2
3546 >>> s2 = s1.with_only_columns([table2.c.b])
3547 >>> print(s2)
3548 SELECT t2.b FROM t1
3549
3550 The preferred way to maintain a specific FROM clause
3551 in the construct, assuming it won't be represented anywhere
3552 else (i.e. not in the WHERE clause, etc.) is to set it using
3553 :meth:`_expression.Select.select_from`::
3554
3555 >>> s1 = select([table1.c.a, table2.c.b]).\
3556 ... select_from(table1.join(table2,
3557 ... table1.c.a==table2.c.a))
3558 >>> s2 = s1.with_only_columns([table2.c.b])
3559 >>> print(s2)
3560 SELECT t2.b FROM t1 JOIN t2 ON t1.a=t2.a
3561
3562 Care should also be taken to use the correct set of column objects
3563 passed to :meth:`_expression.Select.with_only_columns`.
3564 Since the method is
3565 essentially equivalent to calling the :func:`_expression.select`
3566 construct in the first place with the given columns, the columns passed
3567 to :meth:`_expression.Select.with_only_columns`
3568 should usually be a subset of
3569 those which were passed to the :func:`_expression.select`
3570 construct, not those which are available from the ``.c`` collection of
3571 that :func:`_expression.select`. That is::
3572
3573 s = select([table1.c.a, table1.c.b]).select_from(table1)
3574 s = s.with_only_columns([table1.c.b])
3575
3576 and **not**::
3577
3578 # usually incorrect
3579 s = s.with_only_columns([s.c.b])
3580
3581 The latter would produce the SQL::
3582
3583 SELECT b
3584 FROM (SELECT t1.a AS a, t1.b AS b
3585 FROM t1), t1
3586
3587 Since the :func:`_expression.select` construct is essentially
3588 being asked to select both from ``table1`` as well as itself.
3589
3590 """
3591 self._reset_exported()
3592 rc = []
3593 for c in columns:
3594 c = _interpret_as_column_or_from(c)
3595 if isinstance(c, ScalarSelect):
3596 c = c.self_group(against=operators.comma_op)
3597 rc.append(c)
3598 self._raw_columns = rc
3599
3600 @_generative
3601 def where(self, whereclause):
3602 """Return a new :func:`_expression.select` construct with
3603 the given expression added to
3604 its WHERE clause, joined to the existing clause via AND, if any.
3605
3606 """
3607
3608 self.append_whereclause(whereclause)
3609
3610 @_generative
3611 def having(self, having):
3612 """Return a new :func:`_expression.select` construct with
3613 the given expression added to
3614 its HAVING clause, joined to the existing clause via AND, if any.
3615
3616 """
3617 self.append_having(having)
3618
3619 @_generative
3620 def distinct(self, *expr):
3621 r"""Return a new :func:`_expression.select` construct which
3622 will apply DISTINCT to its columns clause.
3623
3624 :param \*expr: optional column expressions. When present,
3625 the PostgreSQL dialect will render a ``DISTINCT ON (<expressions>>)``
3626 construct.
3627
3628 """
3629 if expr:
3630 expr = [_literal_as_label_reference(e) for e in expr]
3631 if isinstance(self._distinct, list):
3632 self._distinct = self._distinct + expr
3633 else:
3634 self._distinct = expr
3635 else:
3636 self._distinct = True
3637
3638 @_generative
3639 def select_from(self, fromclause):
3640 r"""Return a new :func:`_expression.select` construct with the
3641 given FROM expression(s)
3642 merged into its list of FROM objects.
3643
3644 E.g.::
3645
3646 table1 = table('t1', column('a'))
3647 table2 = table('t2', column('b'))
3648 s = select([table1.c.a]).\
3649 select_from(
3650 table1.join(table2, table1.c.a==table2.c.b)
3651 )
3652
3653 The "from" list is a unique set on the identity of each element,
3654 so adding an already present :class:`_schema.Table`
3655 or other selectable
3656 will have no effect. Passing a :class:`_expression.Join` that refers
3657 to an already present :class:`_schema.Table`
3658 or other selectable will have
3659 the effect of concealing the presence of that selectable as
3660 an individual element in the rendered FROM list, instead
3661 rendering it into a JOIN clause.
3662
3663 While the typical purpose of :meth:`_expression.Select.select_from`
3664 is to
3665 replace the default, derived FROM clause with a join, it can
3666 also be called with individual table elements, multiple times
3667 if desired, in the case that the FROM clause cannot be fully
3668 derived from the columns clause::
3669
3670 select([func.count('*')]).select_from(table1)
3671
3672 """
3673 self.append_from(fromclause)
3674
3675 @_generative
3676 def correlate(self, *fromclauses):
3677 r"""Return a new :class:`_expression.Select`
3678 which will correlate the given FROM
3679 clauses to that of an enclosing :class:`_expression.Select`.
3680
3681 Calling this method turns off the :class:`_expression.Select` object's
3682 default behavior of "auto-correlation". Normally, FROM elements
3683 which appear in a :class:`_expression.Select`
3684 that encloses this one via
3685 its :term:`WHERE clause`, ORDER BY, HAVING or
3686 :term:`columns clause` will be omitted from this
3687 :class:`_expression.Select`
3688 object's :term:`FROM clause`.
3689 Setting an explicit correlation collection using the
3690 :meth:`_expression.Select.correlate`
3691 method provides a fixed list of FROM objects
3692 that can potentially take place in this process.
3693
3694 When :meth:`_expression.Select.correlate`
3695 is used to apply specific FROM clauses
3696 for correlation, the FROM elements become candidates for
3697 correlation regardless of how deeply nested this
3698 :class:`_expression.Select`
3699 object is, relative to an enclosing :class:`_expression.Select`
3700 which refers to
3701 the same FROM object. This is in contrast to the behavior of
3702 "auto-correlation" which only correlates to an immediate enclosing
3703 :class:`_expression.Select`.
3704 Multi-level correlation ensures that the link
3705 between enclosed and enclosing :class:`_expression.Select`
3706 is always via
3707 at least one WHERE/ORDER BY/HAVING/columns clause in order for
3708 correlation to take place.
3709
3710 If ``None`` is passed, the :class:`_expression.Select`
3711 object will correlate
3712 none of its FROM entries, and all will render unconditionally
3713 in the local FROM clause.
3714
3715 :param \*fromclauses: a list of one or more
3716 :class:`_expression.FromClause`
3717 constructs, or other compatible constructs (i.e. ORM-mapped
3718 classes) to become part of the correlate collection.
3719
3720 .. seealso::
3721
3722 :meth:`_expression.Select.correlate_except`
3723
3724 :ref:`correlated_subqueries`
3725
3726 """
3727
3728 self._auto_correlate = False
3729 if fromclauses and fromclauses[0] is None:
3730 self._correlate = ()
3731 else:
3732 self._correlate = set(self._correlate).union(
3733 _interpret_as_from(f) for f in fromclauses
3734 )
3735
3736 @_generative
3737 def correlate_except(self, *fromclauses):
3738 r"""Return a new :class:`_expression.Select`
3739 which will omit the given FROM
3740 clauses from the auto-correlation process.
3741
3742 Calling :meth:`_expression.Select.correlate_except` turns off the
3743 :class:`_expression.Select` object's default behavior of
3744 "auto-correlation" for the given FROM elements. An element
3745 specified here will unconditionally appear in the FROM list, while
3746 all other FROM elements remain subject to normal auto-correlation
3747 behaviors.
3748
3749 If ``None`` is passed, the :class:`_expression.Select`
3750 object will correlate
3751 all of its FROM entries.
3752
3753 :param \*fromclauses: a list of one or more
3754 :class:`_expression.FromClause`
3755 constructs, or other compatible constructs (i.e. ORM-mapped
3756 classes) to become part of the correlate-exception collection.
3757
3758 .. seealso::
3759
3760 :meth:`_expression.Select.correlate`
3761
3762 :ref:`correlated_subqueries`
3763
3764 """
3765
3766 self._auto_correlate = False
3767 if fromclauses and fromclauses[0] is None:
3768 self._correlate_except = ()
3769 else:
3770 self._correlate_except = set(self._correlate_except or ()).union(
3771 _interpret_as_from(f) for f in fromclauses
3772 )
3773
3774 def append_correlation(self, fromclause):
3775 """Append the given correlation expression to this
3776 :func:`_expression.select` construct.
3777
3778 This is an **in-place** mutation method; the
3779 :meth:`_expression.Select.correlate` method is preferred,
3780 as it provides standard :term:`method chaining`.
3781
3782 """
3783
3784 self._auto_correlate = False
3785 self._correlate = set(self._correlate).union(
3786 _interpret_as_from(f) for f in fromclause
3787 )
3788
3789 def append_column(self, column):
3790 """Append the given column expression to the columns clause of this
3791 :func:`_expression.select` construct.
3792
3793 E.g.::
3794
3795 my_select.append_column(some_table.c.new_column)
3796
3797 This is an **in-place** mutation method; the
3798 :meth:`_expression.Select.column` method is preferred,
3799 as it provides standard :term:`method chaining`.
3800
3801 See the documentation for :meth:`_expression.Select.with_only_columns`
3802 for guidelines on adding /replacing the columns of a
3803 :class:`_expression.Select` object.
3804
3805 """
3806 self._reset_exported()
3807 column = _interpret_as_column_or_from(column)
3808
3809 if isinstance(column, ScalarSelect):
3810 column = column.self_group(against=operators.comma_op)
3811
3812 self._raw_columns = self._raw_columns + [column]
3813
3814 def append_prefix(self, clause):
3815 """Append the given columns clause prefix expression to this
3816 :func:`_expression.select` construct.
3817
3818 This is an **in-place** mutation method; the
3819 :meth:`_expression.Select.prefix_with` method is preferred,
3820 as it provides standard :term:`method chaining`.
3821
3822 """
3823 clause = _literal_as_text(clause)
3824 self._prefixes = self._prefixes + (clause,)
3825
3826 def append_whereclause(self, whereclause):
3827 """Append the given expression to this :func:`_expression.select`
3828 construct's WHERE criterion.
3829
3830 The expression will be joined to existing WHERE criterion via AND.
3831
3832 This is an **in-place** mutation method; the
3833 :meth:`_expression.Select.where` method is preferred,
3834 as it provides standard :term:`method chaining`.
3835
3836 """
3837
3838 self._reset_exported()
3839 self._whereclause = and_(True_._ifnone(self._whereclause), whereclause)
3840
3841 def append_having(self, having):
3842 """Append the given expression to this :func:`_expression.select`
3843 construct's HAVING criterion.
3844
3845 The expression will be joined to existing HAVING criterion via AND.
3846
3847 This is an **in-place** mutation method; the
3848 :meth:`_expression.Select.having` method is preferred,
3849 as it provides standard :term:`method chaining`.
3850
3851 """
3852 self._reset_exported()
3853 self._having = and_(True_._ifnone(self._having), having)
3854
3855 def append_from(self, fromclause):
3856 """Append the given FromClause expression to this
3857 :func:`_expression.select` construct's FROM clause.
3858
3859 This is an **in-place** mutation method; the
3860 :meth:`_expression.Select.select_from` method is preferred,
3861 as it provides standard :term:`method chaining`.
3862
3863 """
3864 self._reset_exported()
3865 fromclause = _interpret_as_from(fromclause)
3866 self._from_obj = self._from_obj.union([fromclause])
3867
3868 @_memoized_property
3869 def _columns_plus_names(self):
3870 if self.use_labels:
3871 names = set()
3872
3873 def name_for_col(c):
3874 if c._label is None or not c._render_label_in_columns_clause:
3875 return (None, c)
3876
3877 name = c._label
3878 if name in names:
3879 name = c.anon_label
3880 else:
3881 names.add(name)
3882 return name, c
3883
3884 return [
3885 name_for_col(c)
3886 for c in util.unique_list(_select_iterables(self._raw_columns))
3887 ]
3888 else:
3889 return [
3890 (None, c)
3891 for c in util.unique_list(_select_iterables(self._raw_columns))
3892 ]
3893
3894 def _populate_column_collection(self):
3895 for name, c in self._columns_plus_names:
3896 if not hasattr(c, "_make_proxy"):
3897 continue
3898 if name is None:
3899 key = None
3900 elif self.use_labels:
3901 key = c._key_label
3902 if key is not None and key in self.c:
3903 key = c.anon_label
3904 else:
3905 key = None
3906 c._make_proxy(self, key=key, name=name, name_is_truncatable=True)
3907
3908 def _refresh_for_new_column(self, column):
3909 for fromclause in self._froms:
3910 col = fromclause._refresh_for_new_column(column)
3911 if col is not None:
3912 if col in self.inner_columns and self._cols_populated:
3913 our_label = col._key_label if self.use_labels else col.key
3914 if our_label not in self.c:
3915 return col._make_proxy(
3916 self,
3917 name=col._label if self.use_labels else None,
3918 key=col._key_label if self.use_labels else None,
3919 name_is_truncatable=True,
3920 )
3921 return None
3922 return None
3923
3924 def _needs_parens_for_grouping(self):
3925 return (
3926 self._limit_clause is not None
3927 or self._offset_clause is not None
3928 or bool(self._order_by_clause.clauses)
3929 )
3930
3931 def self_group(self, against=None):
3932 """Return a 'grouping' construct as per the
3933 :class:`_expression.ClauseElement` specification.
3934
3935 This produces an element that can be embedded in an expression. Note
3936 that this method is called automatically as needed when constructing
3937 expressions and should not require explicit use.
3938
3939 """
3940 if (
3941 isinstance(against, CompoundSelect)
3942 and not self._needs_parens_for_grouping()
3943 ):
3944 return self
3945 return FromGrouping(self)
3946
3947 def union(self, other, **kwargs):
3948 """Return a SQL ``UNION`` of this select() construct against
3949 the given selectable.
3950
3951 """
3952 return CompoundSelect._create_union(self, other, **kwargs)
3953
3954 def union_all(self, other, **kwargs):
3955 """Return a SQL ``UNION ALL`` of this select() construct against
3956 the given selectable.
3957
3958 """
3959 return CompoundSelect._create_union_all(self, other, **kwargs)
3960
3961 def except_(self, other, **kwargs):
3962 """Return a SQL ``EXCEPT`` of this select() construct against
3963 the given selectable.
3964
3965 """
3966 return CompoundSelect._create_except(self, other, **kwargs)
3967
3968 def except_all(self, other, **kwargs):
3969 """Return a SQL ``EXCEPT ALL`` of this select() construct against
3970 the given selectable.
3971
3972 """
3973 return CompoundSelect._create_except_all(self, other, **kwargs)
3974
3975 def intersect(self, other, **kwargs):
3976 """Return a SQL ``INTERSECT`` of this select() construct against
3977 the given selectable.
3978
3979 """
3980 return CompoundSelect._create_intersect(self, other, **kwargs)
3981
3982 def intersect_all(self, other, **kwargs):
3983 """Return a SQL ``INTERSECT ALL`` of this select() construct
3984 against the given selectable.
3985
3986 """
3987 return CompoundSelect._create_intersect_all(self, other, **kwargs)
3988
3989 def bind(self):
3990 if self._bind:
3991 return self._bind
3992 froms = self._froms
3993 if not froms:
3994 for c in self._raw_columns:
3995 e = c.bind
3996 if e:
3997 self._bind = e
3998 return e
3999 else:
4000 e = list(froms)[0].bind
4001 if e:
4002 self._bind = e
4003 return e
4004
4005 return None
4006
4007 def _set_bind(self, bind):
4008 self._bind = bind
4009
4010 bind = property(bind, _set_bind)
4011
4012
4013class ScalarSelect(Generative, Grouping):
4014 _from_objects = []
4015 _is_from_container = True
4016 _is_implicitly_boolean = False
4017
4018 def __init__(self, element):
4019 self.element = element
4020 self.type = element._scalar_type()
4021
4022 @property
4023 def columns(self):
4024 raise exc.InvalidRequestError(
4025 "Scalar Select expression has no "
4026 "columns; use this object directly "
4027 "within a column-level expression."
4028 )
4029
4030 c = columns
4031
4032 @_generative
4033 def where(self, crit):
4034 """Apply a WHERE clause to the SELECT statement referred to
4035 by this :class:`_expression.ScalarSelect`.
4036
4037 """
4038 self.element = self.element.where(crit)
4039
4040 def self_group(self, **kwargs):
4041 return self
4042
4043
4044class Exists(UnaryExpression):
4045 """Represent an ``EXISTS`` clause."""
4046
4047 __visit_name__ = UnaryExpression.__visit_name__
4048 _from_objects = []
4049
4050 def __init__(self, *args, **kwargs):
4051 """Construct a new :class:`_expression.Exists` against an existing
4052 :class:`_expression.Select` object.
4053
4054 Calling styles are of the following forms::
4055
4056 # use on an existing select()
4057 s = select([table.c.col1]).where(table.c.col2==5)
4058 s_e = exists(s)
4059
4060 # an exists is usually used in a where of another select
4061 # to produce a WHERE EXISTS (SELECT ... )
4062 select([table.c.col1]).where(s_e)
4063
4064 # but can also be used in a select to produce a
4065 # SELECT EXISTS (SELECT ... ) query
4066 select([s_e])
4067
4068 # construct a select() at once
4069 exists(['*'], **select_arguments).where(criterion)
4070
4071 # columns argument is optional, generates "EXISTS (SELECT *)"
4072 # by default.
4073 exists().where(table.c.col2==5)
4074
4075 """
4076 if args and isinstance(args[0], (SelectBase, ScalarSelect)):
4077 s = args[0]
4078 else:
4079 if not args:
4080 args = ([literal_column("*")],)
4081 s = Select(*args, **kwargs).as_scalar().self_group()
4082
4083 UnaryExpression.__init__(
4084 self,
4085 s,
4086 operator=operators.exists,
4087 type_=type_api.BOOLEANTYPE,
4088 wraps_column_expression=True,
4089 )
4090
4091 def select(self, whereclause=None, **params):
4092 return Select([self], whereclause, **params)
4093
4094 def correlate(self, *fromclause):
4095 e = self._clone()
4096 e.element = self.element.correlate(*fromclause).self_group()
4097 return e
4098
4099 def correlate_except(self, *fromclause):
4100 e = self._clone()
4101 e.element = self.element.correlate_except(*fromclause).self_group()
4102 return e
4103
4104 def select_from(self, clause):
4105 """Return a new :class:`_expression.Exists` construct,
4106 applying the given
4107 expression to the :meth:`_expression.Select.select_from`
4108 method of the select
4109 statement contained.
4110
4111 """
4112 e = self._clone()
4113 e.element = self.element.select_from(clause).self_group()
4114 return e
4115
4116 def where(self, clause):
4117 """Return a new :func:`_expression.exists` construct with the
4118 given expression added to
4119 its WHERE clause, joined to the existing clause via AND, if any.
4120
4121 """
4122 e = self._clone()
4123 e.element = self.element.where(clause).self_group()
4124 return e
4125
4126
4127class TextAsFrom(SelectBase):
4128 """Wrap a :class:`_expression.TextClause` construct within a
4129 :class:`_expression.SelectBase`
4130 interface.
4131
4132 This allows the :class:`_expression.TextClause` object to gain a
4133 ``.c`` collection
4134 and other FROM-like capabilities such as
4135 :meth:`_expression.FromClause.alias`,
4136 :meth:`_expression.SelectBase.cte`, etc.
4137
4138 The :class:`.TextAsFrom` construct is produced via the
4139 :meth:`_expression.TextClause.columns`
4140 method - see that method for details.
4141
4142 .. versionadded:: 0.9.0
4143
4144 .. seealso::
4145
4146 :func:`_expression.text`
4147
4148 :meth:`_expression.TextClause.columns`
4149
4150 """
4151
4152 __visit_name__ = "text_as_from"
4153
4154 _textual = True
4155
4156 def __init__(self, text, columns, positional=False):
4157 self.element = text
4158 self.column_args = columns
4159 self.positional = positional
4160
4161 @property
4162 def _bind(self):
4163 return self.element._bind
4164
4165 @_generative
4166 def bindparams(self, *binds, **bind_as_values):
4167 self.element = self.element.bindparams(*binds, **bind_as_values)
4168
4169 def _populate_column_collection(self):
4170 for c in self.column_args:
4171 c._make_proxy(self)
4172
4173 def _copy_internals(self, clone=_clone, **kw):
4174 self._reset_exported()
4175 self.element = clone(self.element, **kw)
4176
4177 def _scalar_type(self):
4178 return self.column_args[0].type
4179
4180
4181class AnnotatedFromClause(Annotated):
4182 def __init__(self, element, values):
4183 # force FromClause to generate their internal
4184 # collections into __dict__
4185 element.c
4186 Annotated.__init__(self, element, values)