diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2021-01-26 22:31:21 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2021-01-26 22:31:21 +0000 |
| commit | 6bba01e1f77bdafbfc3cfb3ff1f3b424608d3d9b (patch) | |
| tree | f4d088aa29297ee0716dcc77bb170b7ef908de2d /lib | |
| parent | b6f83d6013ca4d2bc545754b98bd9400511e0dab (diff) | |
| parent | 22f65156bbe846dea2fb9f87fe4187abe0ed790a (diff) | |
| download | sqlalchemy-6bba01e1f77bdafbfc3cfb3ff1f3b424608d3d9b.tar.gz | |
Merge "Replace with_labels() and apply_labels() in ORM/Core"
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/__init__.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/context.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/loading.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/persistence.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/query.py | 57 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/session.py | 11 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 11 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/__init__.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/coercions.py | 8 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/expression.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/selectable.py | 208 |
12 files changed, 268 insertions, 62 deletions
diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py index 607585460..2d092be65 100644 --- a/lib/sqlalchemy/__init__.py +++ b/lib/sqlalchemy/__init__.py @@ -54,6 +54,10 @@ from .sql import insert # noqa from .sql import intersect # noqa from .sql import intersect_all # noqa from .sql import join # noqa +from .sql import LABEL_STYLE_DEFAULT # noqa +from .sql import LABEL_STYLE_DISAMBIGUATE_ONLY # noqa +from .sql import LABEL_STYLE_NONE # noqa +from .sql import LABEL_STYLE_TABLENAME_PLUS_COL # noqa from .sql import lambda_stmt # noqa from .sql import lateral # noqa from .sql import literal # noqa diff --git a/lib/sqlalchemy/orm/context.py b/lib/sqlalchemy/orm/context.py index 584a07970..f9a0b72fe 100644 --- a/lib/sqlalchemy/orm/context.py +++ b/lib/sqlalchemy/orm/context.py @@ -373,9 +373,11 @@ class ORMFromStatementCompileState(ORMCompileState): if ( isinstance(statement, expression.SelectBase) and not statement._is_textual - and not statement.use_labels + and statement._label_style is util.symbol("LABEL_STYLE_NONE") ): - self.statement = statement.apply_labels() + self.statement = statement.set_label_style( + LABEL_STYLE_TABLENAME_PLUS_COL + ) else: self.statement = statement self.order_by = None diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index 3a85a2d7f..6c38931b4 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -31,6 +31,7 @@ from ..engine.result import ChunkedIteratorResult from ..engine.result import FrozenResult from ..engine.result import SimpleResultMetaData from ..sql import util as sql_util +from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL _new_runid = util.counter() @@ -1396,7 +1397,9 @@ def load_scalar_attributes(mapper, state, attribute_names, passive): result = load_on_ident( session, - future.select(mapper).apply_labels(), + future.select(mapper).set_label_style( + LABEL_STYLE_TABLENAME_PLUS_COL + ), identity_key, refresh_state=state, only_load_props=attribute_names, diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 9ac0c85c6..5a9bc102e 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -54,6 +54,7 @@ from ..sql import operators from ..sql import roles from ..sql import util as sql_util from ..sql import visitors +from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL from ..util import HasMemoized @@ -3008,7 +3009,11 @@ class Mapper( cols = [] for key in col_attribute_names: cols.extend(props[key].columns) - return sql.select(*cols).where(cond).apply_labels() + return ( + sql.select(*cols) + .where(cond) + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + ) def _iterate_to_target_viawpoly(self, mapper): if self.isa(mapper): diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index 42b787580..7ba3a26d0 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -40,6 +40,7 @@ from ..sql.base import Options from ..sql.dml import DeleteDMLState from ..sql.dml import UpdateDMLState from ..sql.elements import BooleanClauseList +from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL def _bulk_insert( @@ -1521,7 +1522,9 @@ def _finalize_insert_update_commands(base_mapper, uowtransaction, states): if toload_now: state.key = base_mapper._identity_key_from_state(state) - stmt = future.select(mapper).apply_labels() + stmt = future.select(mapper).set_label_style( + LABEL_STYLE_TABLENAME_PLUS_COL + ) loading.load_on_ident( uowtransaction.session, stmt, diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 5dd2a8a21..1422fd6a1 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -470,7 +470,7 @@ class Query( """ q = self.enable_eagerloads(False) if with_labels: - q = q.with_labels() + q = q.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) q = q.statement @@ -576,7 +576,11 @@ class Query( return self.enable_eagerloads(False).statement.scalar_subquery() def __clause_element__(self): - return self.enable_eagerloads(False).with_labels().statement + return ( + self.enable_eagerloads(False) + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + .statement + ) @_generative def only_return_tuples(self, value): @@ -637,8 +641,27 @@ class Query( """ self._compile_options += {"_enable_eagerloads": value} - @_generative + @util.deprecated_20( + ":meth:`_orm.Query.with_labels` and :meth:`_orm.Query.apply_labels`", + alternative="Use set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) " + "instead.", + ) def with_labels(self): + return self.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + + apply_labels = with_labels + + @property + def get_label_style(self): + """ + Retrieve the current label style. + + .. versionadded:: 1.4 + + """ + return self._label_style + + def set_label_style(self, style): """Apply column labels to the return value of Query.statement. Indicates that this Query's `statement` accessor should return @@ -650,26 +673,28 @@ class Query( When the `Query` actually issues SQL to load rows, it always uses column labeling. - .. note:: The :meth:`_query.Query.with_labels` method *only* applies + .. note:: The :meth:`_query.Query.set_label_style` method *only* applies the output of :attr:`_query.Query.statement`, and *not* to any of the result-row invoking systems of :class:`_query.Query` itself, e.g. :meth:`_query.Query.first`, :meth:`_query.Query.all`, etc. To execute - a query using :meth:`_query.Query.with_labels`, invoke the + a query using :meth:`_query.Query.set_label_style`, invoke the :attr:`_query.Query.statement` using :meth:`.Session.execute`:: - result = session.execute(query.with_labels().statement) - - - """ - self._label_style = LABEL_STYLE_TABLENAME_PLUS_COL + result = session.execute( + query + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + .statement + ) - apply_labels = with_labels + .. versionadded:: 1.4 - @property - def use_labels(self): - return self._label_style is LABEL_STYLE_TABLENAME_PLUS_COL + """ # noqa + if self._label_style is not style: + self = self._generate() + self._label_style = style + return self @_generative def enable_assertions(self, value): @@ -1259,7 +1284,7 @@ class Query( def _from_self(self, *entities): fromclause = ( - self.with_labels() + self.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) .enable_eagerloads(False) .correlate(None) .subquery() @@ -2903,7 +2928,7 @@ class Query( inner = ( self.enable_eagerloads(False) .add_columns(sql.literal_column("1")) - .with_labels() + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) .statement.with_only_columns(1) ) diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 8a7a64f78..06a69b425 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -37,6 +37,7 @@ from ..sql import dml from ..sql import roles from ..sql import visitors from ..sql.base import CompileState +from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL __all__ = ["Session", "SessionTransaction", "sessionmaker"] @@ -2741,15 +2742,17 @@ class Session(_SessionClassMethods): elif instance is attributes.PASSIVE_CLASS_MISMATCH: return None - # apply_labels() not strictly necessary, however this will ensure that - # tablename_colname style is used which at the moment is asserted - # in a lot of unit tests :) + # set_label_style() not strictly necessary, however this will ensure + # that tablename_colname style is used which at the moment is + # asserted in a lot of unit tests :) load_options = context.QueryContext.default_load_options if populate_existing: load_options += {"_populate_existing": populate_existing} - statement = sql.select(mapper).apply_labels() + statement = sql.select(mapper).set_label_style( + LABEL_STYLE_TABLENAME_PLUS_COL + ) if with_for_update is not None: statement._for_update_arg = query.ForUpdateArg._from_argument( with_for_update diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 837d4d548..c80b8f5a2 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -41,6 +41,7 @@ from .. import sql from .. import util from ..sql import util as sql_util from ..sql import visitors +from ..sql.selectable import LABEL_STYLE_TABLENAME_PLUS_COL def _register_attribute( @@ -487,7 +488,9 @@ class DeferredColumnLoader(LoaderStrategy): if ( loading.load_on_ident( session, - sql.select(localparent).apply_labels(), + sql.select(localparent).set_label_style( + LABEL_STYLE_TABLENAME_PLUS_COL + ), state.key, only_load_props=group, refresh_state=state, @@ -901,7 +904,7 @@ class LazyLoader(AbstractRelationshipLoader, util.MemoizedSlots): stmt = sql.lambda_stmt( lambda: sql.select(self.entity) - .apply_labels() + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) ._set_compile_options(ORMCompileState.default_compile_options), global_track_bound_values=False, lambda_cache=self._query_cache, @@ -1304,7 +1307,7 @@ class SubqueryLoader(PostLoader): # which we'll join onto. # LEGACY: as "q" is a Query, the before_compile() event is invoked # here. - embed_q = q.apply_labels().subquery() + embed_q = q.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL).subquery() left_alias = orm_util.AliasedClass( leftmost_mapper, embed_q, use_mapper_path=True ) @@ -2751,7 +2754,7 @@ class SelectInLoader(PostLoader, util.MemoizedSlots): lambda: sql.select( orm_util.Bundle("pk", *pk_cols), effective_entity ) - .apply_labels() + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) ._set_compile_options(ORMCompileState.default_compile_options) ._set_propagate_attrs( { diff --git a/lib/sqlalchemy/sql/__init__.py b/lib/sqlalchemy/sql/__init__.py index 11795c3b2..7ee0bd8f4 100644 --- a/lib/sqlalchemy/sql/__init__.py +++ b/lib/sqlalchemy/sql/__init__.py @@ -47,6 +47,10 @@ from .expression import intersect_all # noqa from .expression import Join # noqa from .expression import join # noqa from .expression import label # noqa +from .expression import LABEL_STYLE_DEFAULT # noqa +from .expression import LABEL_STYLE_DISAMBIGUATE_ONLY # noqa +from .expression import LABEL_STYLE_NONE # noqa +from .expression import LABEL_STYLE_TABLENAME_PLUS_COL # noqa from .expression import lambda_stmt # noqa from .expression import LambdaElement # noqa from .expression import lateral # noqa diff --git a/lib/sqlalchemy/sql/coercions.py b/lib/sqlalchemy/sql/coercions.py index 05e0a4fcf..3b972be41 100644 --- a/lib/sqlalchemy/sql/coercions.py +++ b/lib/sqlalchemy/sql/coercions.py @@ -67,7 +67,13 @@ def _deep_is_literal(element): return ( not isinstance( element, - (Visitable, schema.SchemaEventTarget, HasCacheKey, Options), + ( + Visitable, + schema.SchemaEventTarget, + HasCacheKey, + Options, + util.langhelpers._symbol, + ), ) and not hasattr(element, "__clause_element__") and ( diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 359f5e533..3eb1443a3 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -158,6 +158,10 @@ from .selectable import HasCTE # noqa from .selectable import HasPrefixes # noqa from .selectable import HasSuffixes # noqa from .selectable import Join # noqa +from .selectable import LABEL_STYLE_DEFAULT # noqa +from .selectable import LABEL_STYLE_DISAMBIGUATE_ONLY # noqa +from .selectable import LABEL_STYLE_NONE # noqa +from .selectable import LABEL_STYLE_TABLENAME_PLUS_COL # noqa from .selectable import Lateral # noqa from .selectable import ReturnsRows # noqa from .selectable import ScalarSelect # noqa diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index 8e478583f..e1cf367c8 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -825,7 +825,7 @@ class FromClause(roles.AnonymizedFromClauseRole, Selectable): this is used to "ping" a derived selectable to add a new column to its .c. collection when a Column has been added to one of the - Table objects it ultimtely derives from. + Table objects it ultimately derives from. If the given selectable hasn't populated its .c. collection yet, it should at least pass on the message to the contained selectables, @@ -849,6 +849,96 @@ class FromClause(roles.AnonymizedFromClauseRole, Selectable): return self.alias(name=name) +LABEL_STYLE_NONE = util.symbol( + "LABEL_STYLE_NONE", + """Label style indicating no automatic labeling should be applied to the + columns clause of a SELECT statement. + + Below, the columns named ``columna`` are both rendered as is, meaning that + the name ``columna`` can only refer to the first occurrence of this name + within a result set, as well as if the statement were used as a subquery:: + + >>> from sqlalchemy import table, column, select, true, LABEL_STYLE_NONE + >>> table1 = table("table1", column("columna"), column("columnb")) + >>> table2 = table("table2", column("columna"), column("columnc")) + >>> print(select(table1, table2).join(table2, true()).set_label_style(LABEL_STYLE_NONE)) + SELECT table1.columna, table1.columnb, table2.columna, table2.columnc + FROM table1 JOIN table2 ON true + + Used with the :meth:`_sql.Select.set_label_style` method. + + .. versionadded:: 1.4 + +""", # noqa E501 +) + +LABEL_STYLE_TABLENAME_PLUS_COL = util.symbol( + "LABEL_STYLE_TABLENAME_PLUS_COL", + """Label style indicating all columns should be labeled as + ``<tablename>_<columnname>`` when generating the columns clause of a SELECT + statement, to disambiguate same-named columns referenced from different + tables, aliases, or subqueries. + + Below, all column names are given a label so that the two same-named + columns ``columna`` are disambiguated as ``table1_columna`` and + ``table2_columna`:: + + >>> from sqlalchemy import table, column, select, true, LABEL_STYLE_TABLENAME_PLUS_COL + >>> table1 = table("table1", column("columna"), column("columnb")) + >>> table2 = table("table2", column("columna"), column("columnc")) + >>> print(select(table1, table2).join(table2, true()).set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL)) + SELECT table1.columna AS table1_columna, table1.columnb AS table1_columnb, table2.columna AS table2_columna, table2.columnc AS table2_columnc + FROM table1 JOIN table2 ON true + + Used with the :meth:`_sql.GenerativeSelect.set_label_style` method. + Equivalent to the legacy method ``Select.apply_labels()``; + :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL` is SQLAlchemy's legacy + auto-labeling style. :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY` provides a + less intrusive approach to disambiguation of same-named column expressions. + + + .. versionadded:: 1.4 + +""", # noqa E501 +) + + +LABEL_STYLE_DISAMBIGUATE_ONLY = util.symbol( + "LABEL_STYLE_DISAMBIGUATE_ONLY", + """Label style indicating that columns with a name that conflicts with + an existing name should be labeled with a semi-anonymizing label + when generating the columns clause of a SELECT statement. + + Below, most column names are left unaffected, except for the second + occurrence of the name ``columna``, which is labeled using the + label ``columna_1`` to disambiguate it from that of ``tablea.columna``:: + + >>> from sqlalchemy import table, column, select, true, LABEL_STYLE_DISAMBIGUATE_ONLY + >>> table1 = table("table1", column("columna"), column("columnb")) + >>> table2 = table("table2", column("columna"), column("columnc")) + >>> print(select(table1, table2).join(table2, true()).set_label_style(LABEL_STYLE_DISAMBIGUATE_ONLY)) + SELECT table1.columna, table1.columnb, table2.columna AS columna_1, table2.columnc + FROM table1 JOIN table2 ON true + + Used with the :meth:`_sql.GenerativeSelect.set_label_style` method, + :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY` is the default labeling style + for all SELECT statements outside of :term:`1.x style` ORM queries. + + .. versionadded:: 1.4 + +""", # noqa: E501, +) + + +LABEL_STYLE_DEFAULT = LABEL_STYLE_DISAMBIGUATE_ONLY +"""The default label style, refers to +:data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY`. + +.. versionadded:: 1.4 + +""" + + class Join(roles.DMLTableRole, FromClause): """Represent a ``JOIN`` construct between two :class:`_expression.FromClause` @@ -1277,7 +1367,12 @@ class Join(roles.DMLTableRole, FromClause): full=self.full, ) else: - return self.select().apply_labels().correlate(None).alias(name) + return ( + self.select() + .set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + .correlate(None) + .alias(name) + ) @util.deprecated_20( ":meth:`_sql.Join.alias`", @@ -1312,7 +1407,7 @@ class Join(roles.DMLTableRole, FromClause): j = alias( select(j.left, j.right).\ select_from(j).\ - apply_labels().\ + set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL).\ correlate(False), name=name ) @@ -2054,9 +2149,7 @@ class Subquery(AliasedReturnsRows): "use the :meth:`_query.Query.scalar_subquery` method.", ) def as_scalar(self): - return self.element._set_label_style( - LABEL_STYLE_NONE - ).scalar_subquery() + return self.element.set_label_style(LABEL_STYLE_NONE).scalar_subquery() class FromGrouping(GroupedElement, FromClause): @@ -2633,7 +2726,7 @@ class SelectBase( """ if self._label_style is not LABEL_STYLE_NONE: - self = self._set_label_style(LABEL_STYLE_NONE) + self = self.set_label_style(LABEL_STYLE_NONE) return ScalarSelect(self) @@ -2760,6 +2853,14 @@ class SelectStatementGrouping(GroupedElement, SelectBase): else: return self + def get_label_style(self): + return self._label_style + + def set_label_style(self, label_style): + return SelectStatementGrouping( + self.element.set_label_style(label_style) + ) + @property def _label_style(self): return self.element._label_style @@ -2854,11 +2955,6 @@ class DeprecatedSelectBaseGenerations(object): self.group_by.non_generative(self, *clauses) -LABEL_STYLE_NONE = util.symbol("LABEL_STYLE_NONE") -LABEL_STYLE_TABLENAME_PLUS_COL = util.symbol("LABEL_STYLE_TABLENAME_PLUS_COL") -LABEL_STYLE_DISAMBIGUATE_ONLY = util.symbol("LABEL_STYLE_DISAMBIGUATE_ONLY") - - class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase): """Base class for SELECT statements where additional elements can be added. @@ -2892,7 +2988,7 @@ class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase): ) def __init__( self, - _label_style=LABEL_STYLE_NONE, + _label_style=LABEL_STYLE_DEFAULT, use_labels=False, limit=None, offset=None, @@ -2901,6 +2997,15 @@ class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase): bind=None, ): if use_labels: + if util.SQLALCHEMY_WARN_20: + util.warn_deprecated_20( + "The use_labels=True keyword argument to GenerativeSelect " + "is deprecated and will be removed in version 2.0. Please " + "use " + "select.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) " + "if you need to replicate this legacy behavior.", + stacklevel=4, + ) _label_style = LABEL_STYLE_TABLENAME_PLUS_COL self._label_style = _label_style @@ -2979,29 +3084,66 @@ class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase): key_share=key_share, ) - @property - def use_labels(self): - return self._label_style is LABEL_STYLE_TABLENAME_PLUS_COL + def get_label_style(self): + """ + Retrieve the current label style. - def apply_labels(self): - """Return a new selectable with the 'use_labels' flag set to True. + .. versionadded:: 1.4 - This will result in column expressions being generated using labels - against their table name, such as "SELECT somecolumn AS - tablename_somecolumn". This allows selectables which contain multiple - FROM clauses to produce a unique set of column names regardless of - name conflicts among the individual FROM clauses. + """ + return self._label_style + + def set_label_style(self, style): + """Return a new selectable with the specified label style. + + There are three "label styles" available, + :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY`, + :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL`, and + :data:`_sql.LABEL_STYLE_NONE`. The default style is + :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL`. + + In modern SQLAlchemy, there is not generally a need to change the + labeling style, as per-expression labels are more effectively used by + making use of the :meth:`_sql.ColumnElement.label` method. In past + versions, :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL` was used to + disambiguate same-named columns from different tables, aliases, or + subqueries; the newer :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY` now + applies labels only to names that conflict with an existing name so + that the impact of this labeling is minimal. + + The rationale for disambiguation is mostly so that all column + expressions are available from a given :attr:`_sql.FromClause.c` + collection when a subquery is created. + + .. versionadded:: 1.4 - the + :meth:`_sql.GenerativeSelect.set_label_style` method replaces the + previous combination of ``.apply_labels()``, ``.with_labels()`` and + ``use_labels=True`` methods and/or parameters. + .. seealso:: - """ - return self._set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + :data:`_sql.LABEL_STYLE_DISAMBIGUATE_ONLY` - def _set_label_style(self, style): + :data:`_sql.LABEL_STYLE_TABLENAME_PLUS_COL` + + :data:`_sql.LABEL_STYLE_NONE` + + :data:`_sql.LABEL_STYLE_DEFAULT` + + """ if self._label_style is not style: self = self._generate() self._label_style = style return self + @util.deprecated_20( + ":meth:`_sql.GenerativeSelect.apply_labels`", + alternative="Use set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) " + "instead.", + ) + def apply_labels(self): + return self.set_label_style(LABEL_STYLE_TABLENAME_PLUS_COL) + @property def _group_by_clause(self): """ClauseList access to group_by_clauses for legacy dialects""" @@ -3525,8 +3667,9 @@ class CompoundSelect(HasCompileState, GenerativeSelect): # ForeignKeys in. this would allow the union() to have all # those fks too. select_0 = self.selects[0] - if self._label_style is not LABEL_STYLE_NONE: - select_0 = select_0._set_label_style(self._label_style) + + if self._label_style is not LABEL_STYLE_DEFAULT: + select_0 = select_0.set_label_style(self._label_style) select_0._generate_fromclause_column_proxies(subquery) # hand-construct the "_proxies" collection to include all @@ -4347,12 +4490,12 @@ class Select( This parameter can also be specified on an existing :class:`_expression.Select` object using the - :meth:`_expression.Select.apply_labels` + :meth:`_expression.Select.set_label_style` method. .. seealso:: - :meth:`_expression.Select.apply_labels` + :meth:`_expression.Select.set_label_style` """ self = cls.__new__(cls) @@ -4917,7 +5060,8 @@ class Select( comparison in the WHERE clause of the statement. The primary purpose of this method is to automatically construct a select statement with all uniquely-named columns, without the need to use - table-qualified labels as :meth:`_expression.Select.apply_labels` + table-qualified labels as + :meth:`_expression.Select.set_label_style` does. When columns are omitted based on foreign key, the referred-to @@ -5263,7 +5407,7 @@ class Select( def _ensure_disambiguated_names(self): if self._label_style is LABEL_STYLE_NONE: - self = self._set_label_style(LABEL_STYLE_DISAMBIGUATE_ONLY) + self = self.set_label_style(LABEL_STYLE_DISAMBIGUATE_ONLY) return self def _generate_columns_plus_names(self, anon_for_dupe_key): |
