Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
selectable.py7266 linesDownload Raw Back to sql
1# sql/selectable.py
2# Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
7
8"""The :class:`_expression.FromClause` class of SQL expression elements,
9representing
10SQL tables and derived rowsets.
11
12"""
13
14from __future__ import annotations
15
16import collections
17from enum import Enum
18import itertools
19from typing import AbstractSet
20from typing import Any as TODO_Any
21from typing import Any
22from typing import Callable
23from typing import cast
24from typing import Dict
25from typing import Generic
26from typing import Iterable
27from typing import Iterator
28from typing import List
29from typing import NamedTuple
30from typing import NoReturn
31from typing import Optional
32from typing import overload
33from typing import Sequence
34from typing import Set
35from typing import Tuple
36from typing import Type
37from typing import TYPE_CHECKING
38from typing import TypeVar
39from typing import Union
40
41from . import cache_key
42from . import coercions
43from . import operators
44from . import roles
45from . import traversals
46from . import type_api
47from . import visitors
48from ._typing import _ColumnsClauseArgument
49from ._typing import _no_kw
50from ._typing import _T
51from ._typing import _TP
52from ._typing import is_column_element
53from ._typing import is_select_statement
54from ._typing import is_subquery
55from ._typing import is_table
56from ._typing import is_text_clause
57from .annotation import Annotated
58from .annotation import SupportsCloneAnnotations
59from .base import _clone
60from .base import _cloned_difference
61from .base import _cloned_intersection
62from .base import _entity_namespace_key
63from .base import _EntityNamespace
64from .base import _expand_cloned
65from .base import _from_objects
66from .base import _generative
67from .base import _never_select_column
68from .base import _NoArg
69from .base import _select_iterables
70from .base import CacheableOptions
71from .base import ColumnCollection
72from .base import ColumnSet
73from .base import CompileState
74from .base import DedupeColumnCollection
75from .base import DialectKWArgs
76from .base import Executable
77from .base import Generative
78from .base import HasCompileState
79from .base import HasMemoized
80from .base import Immutable
81from .coercions import _document_text_coercion
82from .elements import _anonymous_label
83from .elements import BindParameter
84from .elements import BooleanClauseList
85from .elements import ClauseElement
86from .elements import ClauseList
87from .elements import ColumnClause
88from .elements import ColumnElement
89from .elements import DQLDMLClauseElement
90from .elements import GroupedElement
91from .elements import literal_column
92from .elements import TableValuedColumn
93from .elements import UnaryExpression
94from .operators import OperatorType
95from .sqltypes import NULLTYPE
96from .visitors import _TraverseInternalsType
97from .visitors import InternalTraversal
98from .visitors import prefix_anon_map
99from .. import exc
100from .. import util
101from ..util import HasMemoized_ro_memoized_attribute
102from ..util.typing import Literal
103from ..util.typing import Protocol
104from ..util.typing import Self
105
106
107and_ = BooleanClauseList.and_
108
109
110if TYPE_CHECKING:
111    from ._typing import _ColumnExpressionArgument
112    from ._typing import _ColumnExpressionOrStrLabelArgument
113    from ._typing import _FromClauseArgument
114    from ._typing import _JoinTargetArgument
115    from ._typing import _LimitOffsetType
116    from ._typing import _MAYBE_ENTITY
117    from ._typing import _NOT_ENTITY
118    from ._typing import _OnClauseArgument
119    from ._typing import _OnlyColumnArgument
120    from ._typing import _SelectStatementForCompoundArgument
121    from ._typing import _T0
122    from ._typing import _T1
123    from ._typing import _T2
124    from ._typing import _T3
125    from ._typing import _T4
126    from ._typing import _T5
127    from ._typing import _T6
128    from ._typing import _T7
129    from ._typing import _TextCoercedExpressionArgument
130    from ._typing import _TypedColumnClauseArgument as _TCCA
131    from ._typing import _TypeEngineArgument
132    from .base import _AmbiguousTableNameMap
133    from .base import ExecutableOption
134    from .base import ReadOnlyColumnCollection
135    from .cache_key import _CacheKeyTraversalType
136    from .compiler import SQLCompiler
137    from .dml import Delete
138    from .dml import Update
139    from .elements import BinaryExpression
140    from .elements import KeyedColumnElement
141    from .elements import Label
142    from .elements import NamedColumn
143    from .elements import TextClause
144    from .functions import Function
145    from .schema import ForeignKey
146    from .schema import ForeignKeyConstraint
147    from .sqltypes import TableValueType
148    from .type_api import TypeEngine
149    from .visitors import _CloneCallableType
150
151
152_ColumnsClauseElement = Union["FromClause", ColumnElement[Any], "TextClause"]
153_LabelConventionCallable = Callable[
154    [Union["ColumnElement[Any]", "TextClause"]], Optional[str]
155]
156
157
158class _JoinTargetProtocol(Protocol):
159    @util.ro_non_memoized_property
160    def _from_objects(self) -> List[FromClause]: ...
161
162    @util.ro_non_memoized_property
163    def entity_namespace(self) -> _EntityNamespace: ...
164
165
166_JoinTargetElement = Union["FromClause", _JoinTargetProtocol]
167_OnClauseElement = Union["ColumnElement[bool]", _JoinTargetProtocol]
168
169_ForUpdateOfArgument = Union[
170    # single column, Table, ORM entity
171    Union[
172        "_ColumnExpressionArgument[Any]",
173        "_FromClauseArgument",
174    ],
175    # or sequence of column, Table, ORM entity
176    Sequence[
177        Union[
178            "_ColumnExpressionArgument[Any]",
179            "_FromClauseArgument",
180        ]
181    ],
182]
183
184
185_SetupJoinsElement = Tuple[
186    _JoinTargetElement,
187    Optional[_OnClauseElement],
188    Optional["FromClause"],
189    Dict[str, Any],
190]
191
192
193_SelectIterable = Iterable[Union["ColumnElement[Any]", "TextClause"]]
194
195
196class _OffsetLimitParam(BindParameter[int]):
197    inherit_cache = True
198
199    @property
200    def _limit_offset_value(self) -> Optional[int]:
201        return self.effective_value
202
203
204class ReturnsRows(roles.ReturnsRowsRole, DQLDMLClauseElement):
205    """The base-most class for Core constructs that have some concept of
206    columns that can represent rows.
207
208    While the SELECT statement and TABLE are the primary things we think
209    of in this category,  DML like INSERT, UPDATE and DELETE can also specify
210    RETURNING which means they can be used in CTEs and other forms, and
211    PostgreSQL has functions that return rows also.
212
213    .. versionadded:: 1.4
214
215    """
216
217    _is_returns_rows = True
218
219    # sub-elements of returns_rows
220    _is_from_clause = False
221    _is_select_base = False
222    _is_select_statement = False
223    _is_lateral = False
224
225    @property
226    def selectable(self) -> ReturnsRows:
227        return self
228
229    @util.ro_non_memoized_property
230    def _all_selected_columns(self) -> _SelectIterable:
231        """A sequence of column expression objects that represents the
232        "selected" columns of this :class:`_expression.ReturnsRows`.
233
234        This is typically equivalent to .exported_columns except it is
235        delivered in the form of a straight sequence and not  keyed
236        :class:`_expression.ColumnCollection`.
237
238        """
239        raise NotImplementedError()
240
241    def is_derived_from(self, fromclause: Optional[FromClause]) -> bool:
242        """Return ``True`` if this :class:`.ReturnsRows` is
243        'derived' from the given :class:`.FromClause`.
244
245        An example would be an Alias of a Table is derived from that Table.
246
247        """
248        raise NotImplementedError()
249
250    def _generate_fromclause_column_proxies(
251        self,
252        fromclause: FromClause,
253        columns: ColumnCollection[str, KeyedColumnElement[Any]],
254        primary_key: ColumnSet,
255        foreign_keys: Set[KeyedColumnElement[Any]],
256    ) -> None:
257        """Populate columns into an :class:`.AliasedReturnsRows` object."""
258
259        raise NotImplementedError()
260
261    def _refresh_for_new_column(self, column: ColumnElement[Any]) -> None:
262        """reset internal collections for an incoming column being added."""
263        raise NotImplementedError()
264
265    @property
266    def exported_columns(self) -> ReadOnlyColumnCollection[Any, Any]:
267        """A :class:`_expression.ColumnCollection`
268        that represents the "exported"
269        columns of this :class:`_expression.ReturnsRows`.
270
271        The "exported" columns represent the collection of
272        :class:`_expression.ColumnElement`
273        expressions that are rendered by this SQL
274        construct.   There are primary varieties which are the
275        "FROM clause columns" of a FROM clause, such as a table, join,
276        or subquery, the "SELECTed columns", which are the columns in
277        the "columns clause" of a SELECT statement, and the RETURNING
278        columns in a DML statement..
279
280        .. versionadded:: 1.4
281
282        .. seealso::
283
284            :attr:`_expression.FromClause.exported_columns`
285
286            :attr:`_expression.SelectBase.exported_columns`
287        """
288
289        raise NotImplementedError()
290
291
292class ExecutableReturnsRows(Executable, ReturnsRows):
293    """base for executable statements that return rows."""
294
295
296class TypedReturnsRows(ExecutableReturnsRows, Generic[_TP]):
297    """base for a typed executable statements that return rows."""
298
299
300class Selectable(ReturnsRows):
301    """Mark a class as being selectable."""
302
303    __visit_name__ = "selectable"
304
305    is_selectable = True
306
307    def _refresh_for_new_column(self, column: ColumnElement[Any]) -> None:
308        raise NotImplementedError()
309
310    def lateral(self, name: Optional[str] = None) -> LateralFromClause:
311        """Return a LATERAL alias of this :class:`_expression.Selectable`.
312
313        The return value is the :class:`_expression.Lateral` construct also
314        provided by the top-level :func:`_expression.lateral` function.
315
316        .. seealso::
317
318            :ref:`tutorial_lateral_correlation` -  overview of usage.
319
320        """
321        return Lateral._construct(self, name=name)
322
323    @util.deprecated(
324        "1.4",
325        message="The :meth:`.Selectable.replace_selectable` method is "
326        "deprecated, and will be removed in a future release.  Similar "
327        "functionality is available via the sqlalchemy.sql.visitors module.",
328    )
329    @util.preload_module("sqlalchemy.sql.util")
330    def replace_selectable(self, old: FromClause, alias: Alias) -> Self:
331        """Replace all occurrences of :class:`_expression.FromClause`
332        'old' with the given :class:`_expression.Alias`
333        object, returning a copy of this :class:`_expression.FromClause`.
334
335        """
336        return util.preloaded.sql_util.ClauseAdapter(alias).traverse(self)
337
338    def corresponding_column(
339        self, column: KeyedColumnElement[Any], require_embedded: bool = False
340    ) -> Optional[KeyedColumnElement[Any]]:
341        """Given a :class:`_expression.ColumnElement`, return the exported
342        :class:`_expression.ColumnElement` object from the
343        :attr:`_expression.Selectable.exported_columns`
344        collection of this :class:`_expression.Selectable`
345        which corresponds to that
346        original :class:`_expression.ColumnElement` via a common ancestor
347        column.
348
349        :param column: the target :class:`_expression.ColumnElement`
350                      to be matched.
351
352        :param require_embedded: only return corresponding columns for
353         the given :class:`_expression.ColumnElement`, if the given
354         :class:`_expression.ColumnElement`
355         is actually present within a sub-element
356         of this :class:`_expression.Selectable`.
357         Normally the column will match if
358         it merely shares a common ancestor with one of the exported
359         columns of this :class:`_expression.Selectable`.
360
361        .. seealso::
362
363            :attr:`_expression.Selectable.exported_columns` - the
364            :class:`_expression.ColumnCollection`
365            that is used for the operation.
366
367            :meth:`_expression.ColumnCollection.corresponding_column`
368            - implementation
369            method.
370
371        """
372
373        return self.exported_columns.corresponding_column(
374            column, require_embedded
375        )
376
377
378class HasPrefixes:
379    _prefixes: Tuple[Tuple[DQLDMLClauseElement, str], ...] = ()
380
381    _has_prefixes_traverse_internals: _TraverseInternalsType = [
382        ("_prefixes", InternalTraversal.dp_prefix_sequence)
383    ]
384
385    @_generative
386    @_document_text_coercion(
387        "prefixes",
388        ":meth:`_expression.HasPrefixes.prefix_with`",
389        ":paramref:`.HasPrefixes.prefix_with.*prefixes`",
390    )
391    def prefix_with(
392        self,
393        *prefixes: _TextCoercedExpressionArgument[Any],
394        dialect: str = "*",
395    ) -> Self:
396        r"""Add one or more expressions following the statement keyword, i.e.
397        SELECT, INSERT, UPDATE, or DELETE. Generative.
398
399        This is used to support backend-specific prefix keywords such as those
400        provided by MySQL.
401
402        E.g.::
403
404            stmt = table.insert().prefix_with("LOW_PRIORITY", dialect="mysql")
405
406            # MySQL 5.7 optimizer hints
407            stmt = select(table).prefix_with("/*+ BKA(t1) */", dialect="mysql")
408
409        Multiple prefixes can be specified by multiple calls
410        to :meth:`_expression.HasPrefixes.prefix_with`.
411
412        :param \*prefixes: textual or :class:`_expression.ClauseElement`
413         construct which
414         will be rendered following the INSERT, UPDATE, or DELETE
415         keyword.
416        :param dialect: optional string dialect name which will
417         limit rendering of this prefix to only that dialect.
418
419        """
420        self._prefixes = self._prefixes + tuple(
421            [
422                (coercions.expect(roles.StatementOptionRole, p), dialect)
423                for p in prefixes
424            ]
425        )
426        return self
427
428
429class HasSuffixes:
430    _suffixes: Tuple[Tuple[DQLDMLClauseElement, str], ...] = ()
431
432    _has_suffixes_traverse_internals: _TraverseInternalsType = [
433        ("_suffixes", InternalTraversal.dp_prefix_sequence)
434    ]
435
436    @_generative
437    @_document_text_coercion(
438        "suffixes",
439        ":meth:`_expression.HasSuffixes.suffix_with`",
440        ":paramref:`.HasSuffixes.suffix_with.*suffixes`",
441    )
442    def suffix_with(
443        self,
444        *suffixes: _TextCoercedExpressionArgument[Any],
445        dialect: str = "*",
446    ) -> Self:
447        r"""Add one or more expressions following the statement as a whole.
448
449        This is used to support backend-specific suffix keywords on
450        certain constructs.
451
452        E.g.::
453
454            stmt = (
455                select(col1, col2)
456                .cte()
457                .suffix_with(
458                    "cycle empno set y_cycle to 1 default 0", dialect="oracle"
459                )
460            )
461
462        Multiple suffixes can be specified by multiple calls
463        to :meth:`_expression.HasSuffixes.suffix_with`.
464
465        :param \*suffixes: textual or :class:`_expression.ClauseElement`
466         construct which
467         will be rendered following the target clause.
468        :param dialect: Optional string dialect name which will
469         limit rendering of this suffix to only that dialect.
470
471        """
472        self._suffixes = self._suffixes + tuple(
473            [
474                (coercions.expect(roles.StatementOptionRole, p), dialect)
475                for p in suffixes
476            ]
477        )
478        return self
479
480
481class HasHints:
482    _hints: util.immutabledict[Tuple[FromClause, str], str] = (
483        util.immutabledict()
484    )
485    _statement_hints: Tuple[Tuple[str, str], ...] = ()
486
487    _has_hints_traverse_internals: _TraverseInternalsType = [
488        ("_statement_hints", InternalTraversal.dp_statement_hint_list),
489        ("_hints", InternalTraversal.dp_table_hint_list),
490    ]
491
492    @_generative
493    def with_statement_hint(self, text: str, dialect_name: str = "*") -> Self:
494        """Add a statement hint to this :class:`_expression.Select` or
495        other selectable object.
496
497        .. tip::
498
499            :meth:`_expression.Select.with_statement_hint` generally adds hints
500            **at the trailing end** of a SELECT statement.  To place
501            dialect-specific hints such as optimizer hints at the **front** of
502            the SELECT statement after the SELECT keyword, use the
503            :meth:`_expression.Select.prefix_with` method for an open-ended
504            space, or for table-specific hints the
505            :meth:`_expression.Select.with_hint` may be used, which places
506            hints in a dialect-specific location.
507
508        This method is similar to :meth:`_expression.Select.with_hint` except
509        that it does not require an individual table, and instead applies to
510        the statement as a whole.
511
512        Hints here are specific to the backend database and may include
513        directives such as isolation levels, file directives, fetch directives,
514        etc.
515
516        .. seealso::
517
518            :meth:`_expression.Select.with_hint`
519
520            :meth:`_expression.Select.prefix_with` - generic SELECT prefixing
521            which also can suit some database-specific HINT syntaxes such as
522            MySQL or Oracle Database optimizer hints
523
524        """
525        return self._with_hint(None, text, dialect_name)
526
527    @_generative
528    def with_hint(
529        self,
530        selectable: _FromClauseArgument,
531        text: str,
532        dialect_name: str = "*",
533    ) -> Self:
534        r"""Add an indexing or other executional context hint for the given
535        selectable to this :class:`_expression.Select` or other selectable
536        object.
537
538        .. tip::
539
540            The :meth:`_expression.Select.with_hint` method adds hints that are
541            **specific to a single table** to a statement, in a location that
542            is **dialect-specific**.  To add generic optimizer hints to the
543            **beginning** of a statement ahead of the SELECT keyword such as
544            for MySQL or Oracle Database, use the
545            :meth:`_expression.Select.prefix_with` method.  To add optimizer
546            hints to the **end** of a statement such as for PostgreSQL, use the
547            :meth:`_expression.Select.with_statement_hint` method.
548
549        The text of the hint is rendered in the appropriate
550        location for the database backend in use, relative
551        to the given :class:`_schema.Table` or :class:`_expression.Alias`
552        passed as the
553        ``selectable`` argument. The dialect implementation
554        typically uses Python string substitution syntax
555        with the token ``%(name)s`` to render the name of
556        the table or alias. E.g. when using Oracle Database, the
557        following::
558
559            select(mytable).with_hint(mytable, "index(%(name)s ix_mytable)")
560
561        Would render SQL as:
562
563        .. sourcecode:: sql
564
565            select /*+ index(mytable ix_mytable) */ ... from mytable
566
567        The ``dialect_name`` option will limit the rendering of a particular
568        hint to a particular backend. Such as, to add hints for both Oracle
569        Database and MSSql simultaneously::
570
571            select(mytable).with_hint(
572                mytable, "index(%(name)s ix_mytable)", "oracle"
573            ).with_hint(mytable, "WITH INDEX ix_mytable", "mssql")
574
575        .. seealso::
576
577            :meth:`_expression.Select.with_statement_hint`
578
579            :meth:`_expression.Select.prefix_with` - generic SELECT prefixing
580            which also can suit some database-specific HINT syntaxes such as
581            MySQL or Oracle Database optimizer hints
582
583        """
584
585        return self._with_hint(selectable, text, dialect_name)
586
587    def _with_hint(
588        self,
589        selectable: Optional[_FromClauseArgument],
590        text: str,
591        dialect_name: str,
592    ) -> Self:
593        if selectable is None:
594            self._statement_hints += ((dialect_name, text),)
595        else:
596            self._hints = self._hints.union(
597                {
598                    (
599                        coercions.expect(roles.FromClauseRole, selectable),
600                        dialect_name,
601                    ): text
602                }
603            )
604        return self
605
606
607class FromClause(roles.AnonymizedFromClauseRole, Selectable):
608    """Represent an element that can be used within the ``FROM``
609    clause of a ``SELECT`` statement.
610
611    The most common forms of :class:`_expression.FromClause` are the
612    :class:`_schema.Table` and the :func:`_expression.select` constructs.  Key
613    features common to all :class:`_expression.FromClause` objects include:
614
615    * a :attr:`.c` collection, which provides per-name access to a collection
616      of :class:`_expression.ColumnElement` objects.
617    * a :attr:`.primary_key` attribute, which is a collection of all those
618      :class:`_expression.ColumnElement`
619      objects that indicate the ``primary_key`` flag.
620    * Methods to generate various derivations of a "from" clause, including
621      :meth:`_expression.FromClause.alias`,
622      :meth:`_expression.FromClause.join`,
623      :meth:`_expression.FromClause.select`.
624
625
626    """
627
628    __visit_name__ = "fromclause"
629    named_with_column = False
630
631    @util.ro_non_memoized_property
632    def _hide_froms(self) -> Iterable[FromClause]:
633        return ()
634
635    _is_clone_of: Optional[FromClause]
636
637    _columns: ColumnCollection[Any, Any]
638
639    schema: Optional[str] = None
640    """Define the 'schema' attribute for this :class:`_expression.FromClause`.
641
642    This is typically ``None`` for most objects except that of
643    :class:`_schema.Table`, where it is taken as the value of the
644    :paramref:`_schema.Table.schema` argument.
645
646    """
647
648    is_selectable = True
649    _is_from_clause = True
650    _is_join = False
651
652    _use_schema_map = False
653
654    def select(self) -> Select[Any]:
655        r"""Return a SELECT of this :class:`_expression.FromClause`.
656
657
658        e.g.::
659
660            stmt = some_table.select().where(some_table.c.id == 5)
661
662        .. seealso::
663
664            :func:`_expression.select` - general purpose
665            method which allows for arbitrary column lists.
666
667        """
668        return Select(self)
669
670    def join(
671        self,
672        right: _FromClauseArgument,
673        onclause: Optional[_ColumnExpressionArgument[bool]] = None,
674        isouter: bool = False,
675        full: bool = False,
676    ) -> Join:
677        """Return a :class:`_expression.Join` from this
678        :class:`_expression.FromClause`
679        to another :class:`FromClause`.
680
681        E.g.::
682
683            from sqlalchemy import join
684
685            j = user_table.join(
686                address_table, user_table.c.id == address_table.c.user_id
687            )
688            stmt = select(user_table).select_from(j)
689
690        would emit SQL along the lines of:
691
692        .. sourcecode:: sql
693
694            SELECT user.id, user.name FROM user
695            JOIN address ON user.id = address.user_id
696
697        :param right: the right side of the join; this is any
698         :class:`_expression.FromClause` object such as a
699         :class:`_schema.Table` object, and
700         may also be a selectable-compatible object such as an ORM-mapped
701         class.
702
703        :param onclause: a SQL expression representing the ON clause of the
704         join.  If left at ``None``, :meth:`_expression.FromClause.join`
705         will attempt to
706         join the two tables based on a foreign key relationship.
707
708        :param isouter: if True, render a LEFT OUTER JOIN, instead of JOIN.
709
710        :param full: if True, render a FULL OUTER JOIN, instead of LEFT OUTER
711         JOIN.  Implies :paramref:`.FromClause.join.isouter`.
712
713        .. seealso::
714
715            :func:`_expression.join` - standalone function
716
717            :class:`_expression.Join` - the type of object produced
718
719        """
720
721        return Join(self, right, onclause, isouter, full)
722
723    def outerjoin(
724        self,
725        right: _FromClauseArgument,
726        onclause: Optional[_ColumnExpressionArgument[bool]] = None,
727        full: bool = False,
728    ) -> Join:
729        """Return a :class:`_expression.Join` from this
730        :class:`_expression.FromClause`
731        to another :class:`FromClause`, with the "isouter" flag set to
732        True.
733
734        E.g.::
735
736            from sqlalchemy import outerjoin
737
738            j = user_table.outerjoin(
739                address_table, user_table.c.id == address_table.c.user_id
740            )
741
742        The above is equivalent to::
743
744            j = user_table.join(
745                address_table, user_table.c.id == address_table.c.user_id, isouter=True
746            )
747
748        :param right: the right side of the join; this is any
749         :class:`_expression.FromClause` object such as a
750         :class:`_schema.Table` object, and
751         may also be a selectable-compatible object such as an ORM-mapped
752         class.
753
754        :param onclause: a SQL expression representing the ON clause of the
755         join.  If left at ``None``, :meth:`_expression.FromClause.join`
756         will attempt to
757         join the two tables based on a foreign key relationship.
758
759        :param full: if True, render a FULL OUTER JOIN, instead of
760         LEFT OUTER JOIN.
761
762        .. seealso::
763
764            :meth:`_expression.FromClause.join`
765
766            :class:`_expression.Join`
767
768        """  # noqa: E501
769
770        return Join(self, right, onclause, True, full)
771
772    def alias(
773        self, name: Optional[str] = None, flat: bool = False
774    ) -> NamedFromClause:
775        """Return an alias of this :class:`_expression.FromClause`.
776
777        E.g.::
778
779            a2 = some_table.alias("a2")
780
781        The above code creates an :class:`_expression.Alias`
782        object which can be used
783        as a FROM clause in any SELECT statement.
784
785        .. seealso::
786
787            :ref:`tutorial_using_aliases`
788
789            :func:`_expression.alias`
790
791        """
792
793        return Alias._construct(self, name=name)
794
795    def tablesample(
796        self,
797        sampling: Union[float, Function[Any]],
798        name: Optional[str] = None,
799        seed: Optional[roles.ExpressionElementRole[Any]] = None,
800    ) -> TableSample:
801        """Return a TABLESAMPLE alias of this :class:`_expression.FromClause`.
802
803        The return value is the :class:`_expression.TableSample`
804        construct also
805        provided by the top-level :func:`_expression.tablesample` function.
806
807        .. seealso::
808
809            :func:`_expression.tablesample` - usage guidelines and parameters
810
811        """
812        return TableSample._construct(
813            self, sampling=sampling, name=name, seed=seed
814        )
815
816    def is_derived_from(self, fromclause: Optional[FromClause]) -> bool:
817        """Return ``True`` if this :class:`_expression.FromClause` is
818        'derived' from the given ``FromClause``.
819
820        An example would be an Alias of a Table is derived from that Table.
821
822        """
823        # this is essentially an "identity" check in the base class.
824        # Other constructs override this to traverse through
825        # contained elements.
826        return fromclause in self._cloned_set
827
828    def _is_lexical_equivalent(self, other: FromClause) -> bool:
829        """Return ``True`` if this :class:`_expression.FromClause` and
830        the other represent the same lexical identity.
831
832        This tests if either one is a copy of the other, or
833        if they are the same via annotation identity.
834
835        """
836        return bool(self._cloned_set.intersection(other._cloned_set))
837
838    @util.ro_non_memoized_property
839    def description(self) -> str:
840        """A brief description of this :class:`_expression.FromClause`.
841
842        Used primarily for error message formatting.
843
844        """
845        return getattr(self, "name", self.__class__.__name__ + " object")
846
847    def _generate_fromclause_column_proxies(
848        self,
849        fromclause: FromClause,
850        columns: ColumnCollection[str, KeyedColumnElement[Any]],
851        primary_key: ColumnSet,
852        foreign_keys: Set[KeyedColumnElement[Any]],
853    ) -> None:
854        columns._populate_separate_keys(
855            col._make_proxy(
856                fromclause, primary_key=primary_key, foreign_keys=foreign_keys
857            )
858            for col in self.c
859        )
860
861    @util.ro_non_memoized_property
862    def exported_columns(
863        self,
864    ) -> ReadOnlyColumnCollection[str, KeyedColumnElement[Any]]:
865        """A :class:`_expression.ColumnCollection`
866        that represents the "exported"
867        columns of this :class:`_expression.Selectable`.
868
869        The "exported" columns for a :class:`_expression.FromClause`
870        object are synonymous
871        with the :attr:`_expression.FromClause.columns` collection.
872
873        .. versionadded:: 1.4
874
875        .. seealso::
876
877            :attr:`_expression.Selectable.exported_columns`
878
879            :attr:`_expression.SelectBase.exported_columns`
880
881
882        """
883        return self.c
884
885    @util.ro_non_memoized_property
886    def columns(
887        self,
888    ) -> ReadOnlyColumnCollection[str, KeyedColumnElement[Any]]:
889        """A named-based collection of :class:`_expression.ColumnElement`
890        objects maintained by this :class:`_expression.FromClause`.
891
892        The :attr:`.columns`, or :attr:`.c` collection, is the gateway
893        to the construction of SQL expressions using table-bound or
894        other selectable-bound columns::
895
896            select(mytable).where(mytable.c.somecolumn == 5)
897
898        :return: a :class:`.ColumnCollection` object.
899
900        """
901        return self.c
902
903    @util.ro_memoized_property
904    def c(self) -> ReadOnlyColumnCollection[str, KeyedColumnElement[Any]]:
905        """
906        A synonym for :attr:`.FromClause.columns`
907
908        :return: a :class:`.ColumnCollection`
909
910        """
911        if "_columns" not in self.__dict__:
912            self._setup_collections()
913        return self._columns.as_readonly()
914
915    def _setup_collections(self) -> None:
916        with util.mini_gil:
917            # detect another thread that raced ahead
918            if "_columns" in self.__dict__:
919                assert "primary_key" in self.__dict__
920                assert "foreign_keys" in self.__dict__
921                return
922
923            _columns: ColumnCollection[Any, Any] = ColumnCollection()
924            primary_key = ColumnSet()
925            foreign_keys: Set[KeyedColumnElement[Any]] = set()
926
927            self._populate_column_collection(
928                columns=_columns,
929                primary_key=primary_key,
930                foreign_keys=foreign_keys,
931            )
932
933            # assigning these three collections separately is not itself
934            # atomic, but greatly reduces the surface for problems
935            self._columns = _columns
936            self.primary_key = primary_key  # type: ignore
937            self.foreign_keys = foreign_keys  # type: ignore
938
939    @util.ro_non_memoized_property
940    def entity_namespace(self) -> _EntityNamespace:
941        """Return a namespace used for name-based access in SQL expressions.
942
943        This is the namespace that is used to resolve "filter_by()" type
944        expressions, such as::
945
946            stmt.filter_by(address="some address")
947
948        It defaults to the ``.c`` collection, however internally it can
949        be overridden using the "entity_namespace" annotation to deliver
950        alternative results.
951
952        """
953        return self.c
954
955    @util.ro_memoized_property
956    def primary_key(self) -> Iterable[NamedColumn[Any]]:
957        """Return the iterable collection of :class:`_schema.Column` objects
958        which comprise the primary key of this :class:`_selectable.FromClause`.
959
960        For a :class:`_schema.Table` object, this collection is represented
961        by the :class:`_schema.PrimaryKeyConstraint` which itself is an
962        iterable collection of :class:`_schema.Column` objects.
963
964        """
965        self._setup_collections()
966        return self.primary_key
967
968    @util.ro_memoized_property
969    def foreign_keys(self) -> Iterable[ForeignKey]:
970        """Return the collection of :class:`_schema.ForeignKey` marker objects
971        which this FromClause references.
972
973        Each :class:`_schema.ForeignKey` is a member of a
974        :class:`_schema.Table`-wide
975        :class:`_schema.ForeignKeyConstraint`.
976
977        .. seealso::
978
979            :attr:`_schema.Table.foreign_key_constraints`
980
981        """
982        self._setup_collections()
983        return self.foreign_keys
984
985    def _reset_column_collection(self) -> None:
986        """Reset the attributes linked to the ``FromClause.c`` attribute.
987
988        This collection is separate from all the other memoized things
989        as it has shown to be sensitive to being cleared out in situations
990        where enclosing code, typically in a replacement traversal scenario,
991        has already established strong relationships
992        with the exported columns.
993
994        The collection is cleared for the case where a table is having a
995        column added to it as well as within a Join during copy internals.
996
997        """
998
999        for key in ["_columns", "columns", "c", "primary_key", "foreign_keys"]:
1000            self.__dict__.pop(key, None)
1001
1002    @util.ro_non_memoized_property
1003    def _select_iterable(self) -> _SelectIterable:
1004        return (c for c in self.c if not _never_select_column(c))
1005
1006    @property
1007    def _cols_populated(self) -> bool:
1008        return "_columns" in self.__dict__
1009
1010    def _populate_column_collection(
1011        self,
1012        columns: ColumnCollection[str, KeyedColumnElement[Any]],
1013        primary_key: ColumnSet,
1014        foreign_keys: Set[KeyedColumnElement[Any]],
1015    ) -> None:
1016        """Called on subclasses to establish the .c collection.
1017
1018        Each implementation has a different way of establishing
1019        this collection.
1020
1021        """
1022
1023    def _refresh_for_new_column(self, column: ColumnElement[Any]) -> None:
1024        """Given a column added to the .c collection of an underlying
1025        selectable, produce the local version of that column, assuming this
1026        selectable ultimately should proxy this column.
1027
1028        this is used to "ping" a derived selectable to add a new column
1029        to its .c. collection when a Column has been added to one of the
1030        Table objects it ultimately derives from.
1031
1032        If the given selectable hasn't populated its .c. collection yet,
1033        it should at least pass on the message to the contained selectables,
1034        but it will return None.
1035
1036        This method is currently used by Declarative to allow Table
1037        columns to be added to a partially constructed inheritance
1038        mapping that may have already produced joins.  The method
1039        isn't public right now, as the full span of implications
1040        and/or caveats aren't yet clear.
1041
1042        It's also possible that this functionality could be invoked by
1043        default via an event, which would require that
1044        selectables maintain a weak referencing collection of all
1045        derivations.
1046
1047        """
1048        self._reset_column_collection()
1049
1050    def _anonymous_fromclause(
1051        self, *, name: Optional[str] = None, flat: bool = False
1052    ) -> FromClause:
1053        return self.alias(name=name)
1054
1055    if TYPE_CHECKING:
1056
1057        def self_group(
1058            self, against: Optional[OperatorType] = None
1059        ) -> Union[FromGrouping, Self]: ...
1060
1061
1062class NamedFromClause(FromClause):
1063    """A :class:`.FromClause` that has a name.
1064
1065    Examples include tables, subqueries, CTEs, aliased tables.
1066
1067    .. versionadded:: 2.0
1068
1069    """
1070
1071    named_with_column = True
1072
1073    name: str
1074
1075    @util.preload_module("sqlalchemy.sql.sqltypes")
1076    def table_valued(self) -> TableValuedColumn[Any]:
1077        """Return a :class:`_sql.TableValuedColumn` object for this
1078        :class:`_expression.FromClause`.
1079
1080        A :class:`_sql.TableValuedColumn` is a :class:`_sql.ColumnElement` that
1081        represents a complete row in a table. Support for this construct is
1082        backend dependent, and is supported in various forms by backends
1083        such as PostgreSQL, Oracle Database and SQL Server.
1084
1085        E.g.:
1086
1087        .. sourcecode:: pycon+sql
1088
1089            >>> from sqlalchemy import select, column, func, table
1090            >>> a = table("a", column("id"), column("x"), column("y"))
1091            >>> stmt = select(func.row_to_json(a.table_valued()))
1092            >>> print(stmt)
1093            {printsql}SELECT row_to_json(a) AS row_to_json_1
1094            FROM a
1095
1096        .. versionadded:: 1.4.0b2
1097
1098        .. seealso::
1099
1100            :ref:`tutorial_functions` - in the :ref:`unified_tutorial`
1101
1102        """
1103        return TableValuedColumn(self, type_api.TABLEVALUE)
1104
1105
1106class SelectLabelStyle(Enum):
1107    """Label style constants that may be passed to
1108    :meth:`_sql.Select.set_label_style`."""
1109
1110    LABEL_STYLE_NONE = 0
1111    """Label style indicating no automatic labeling should be applied to the
1112    columns clause of a SELECT statement.
1113
1114    Below, the columns named ``columna`` are both rendered as is, meaning that
1115    the name ``columna`` can only refer to the first occurrence of this name
1116    within a result set, as well as if the statement were used as a subquery:
1117
1118    .. sourcecode:: pycon+sql
1119
1120        >>> from sqlalchemy import table, column, select, true, LABEL_STYLE_NONE
1121        >>> table1 = table("table1", column("columna"), column("columnb"))
1122        >>> table2 = table("table2", column("columna"), column("columnc"))
1123        >>> print(
1124        ...     select(table1, table2)
1125        ...     .join(table2, true())
1126        ...     .set_label_style(LABEL_STYLE_NONE)
1127        ... )
1128        {printsql}SELECT table1.columna, table1.columnb, table2.columna, table2.columnc
1129        FROM table1 JOIN table2 ON true
1130
1131    Used with the :meth:`_sql.Select.set_label_style` method.
1132
1133    .. versionadded:: 1.4
1134
1135    """  # noqa: E501
1136
1137    LABEL_STYLE_TABLENAME_PLUS_COL = 1
1138    """Label style indicating all columns should be labeled as
1139    ``<tablename>_<columnname>`` when generating the columns clause of a SELECT
1140    statement, to disambiguate same-named columns referenced from different
1141    tables, aliases, or subqueries.
1142
1143    Below, all column names are given a label so that the two same-named
1144    columns ``columna`` are disambiguated as ``table1_columna`` and
1145    ``table2_columna``:
1146
1147    .. sourcecode:: pycon+sql
1148
1149        >>> from sqlalchemy import (
1150        ...     table,
1151        ...     column,
1152        ...     select,
1153        ...     true,
1154        ...     LABEL_STYLE_TABLENAME_PLUS_COL,
1155        ... )
1156        >>> table1 = table("table1", column("columna"), column("columnb"))
1157        >>> table2 = table("table2", column("columna"), column("columnc"))
1158        >>> print(
1159        ...     select(table1, table2)
1160        ...     .join(table2, true())
1161        ...     .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)
1162        ... )
1163        {printsql}SELECT table1.columna AS table1_columna, table1.columnb AS table1_columnb, table2.columna AS table2_columna, table2.columnc AS table2_columnc
1164        FROM table1 JOIN table2 ON true
1165
1166    Used with the :meth:`_sql.GenerativeSelect.set_label_style` method.
1167    Equivalent to the legacy method ``Select.apply_labels()``;
1168    :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL` is SQLAlchemy's legacy
1169    auto-labeling style. :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY` provides a
1170    less intrusive approach to disambiguation of same-named column expressions.
1171
1172
1173    .. versionadded:: 1.4
1174
1175    """  # noqa: E501
1176
1177    LABEL_STYLE_DISAMBIGUATE_ONLY = 2
1178    """Label style indicating that columns with a name that conflicts with
1179    an existing name should be labeled with a semi-anonymizing label
1180    when generating the columns clause of a SELECT statement.
1181
1182    Below, most column names are left unaffected, except for the second
1183    occurrence of the name ``columna``, which is labeled using the
1184    label ``columna_1`` to disambiguate it from that of ``tablea.columna``:
1185
1186    .. sourcecode:: pycon+sql
1187
1188        >>> from sqlalchemy import (
1189        ...     table,
1190        ...     column,
1191        ...     select,
1192        ...     true,
1193        ...     LABEL_STYLE_DISAMBIGUATE_ONLY,
1194        ... )
1195        >>> table1 = table("table1", column("columna"), column("columnb"))
1196        >>> table2 = table("table2", column("columna"), column("columnc"))
1197        >>> print(
1198        ...     select(table1, table2)
1199        ...     .join(table2, true())
1200        ...     .set_label_style(LABEL_STYLE_DISAMBIGUATE_ONLY)

Showing the first 1,200 of 7266 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai