diff options
author | mike bayer <mike_mp@zzzcomputing.com> | 2019-08-30 15:21:08 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2019-08-30 15:21:08 +0000 |
commit | f499671ccc30cd42d6e3beb6ddec60e104bff9c5 (patch) | |
tree | def2ccba55e3d4231bc2019472c69a5e2eaa6d97 /lib/sqlalchemy/sql/elements.py | |
parent | 2b042b6d18dc527c12b2ef1239bfe5ee2b658930 (diff) | |
parent | 3bb402ff8ed980ae393def7462b1da49c0e0a8a7 (diff) | |
download | sqlalchemy-f499671ccc30cd42d6e3beb6ddec60e104bff9c5.tar.gz |
Merge "Label simple column transformations as the column name"
Diffstat (limited to 'lib/sqlalchemy/sql/elements.py')
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index e2df1adc2..669519d1a 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -914,6 +914,42 @@ class ColumnElement( return self._anon_label(getattr(self, "_label", None)) +class WrapsColumnExpression(object): + """Mixin that defines a :class:`.ColumnElement` as a wrapper with special + labeling behavior for an expression that already has a name. + + .. versionadded:: 1.4 + + .. seealso:: + + :ref:`change_4449` + + + """ + + @property + def wrapped_column_expression(self): + raise NotImplementedError() + + @property + def _label(self): + wce = self.wrapped_column_expression + if hasattr(wce, "_label"): + return wce._label + else: + return None + + @property + def anon_label(self): + wce = self.wrapped_column_expression + if hasattr(wce, "name"): + return wce.name + elif hasattr(wce, "anon_label"): + return wce.anon_label + else: + return super(WrapsColumnExpression, self).anon_label + + class BindParameter(roles.InElementRole, ColumnElement): r"""Represent a "bound expression". @@ -2477,7 +2513,7 @@ def literal_column(text, type_=None): return ColumnClause(text, type_=type_, is_literal=True) -class Cast(ColumnElement): +class Cast(WrapsColumnExpression, ColumnElement): """Represent a ``CAST`` expression. :class:`.Cast` is produced using the :func:`.cast` factory function, @@ -2582,8 +2618,12 @@ class Cast(ColumnElement): def _from_objects(self): return self.clause._from_objects + @property + def wrapped_column_expression(self): + return self.clause + -class TypeCoerce(ColumnElement): +class TypeCoerce(WrapsColumnExpression, ColumnElement): """Represent a Python-side type-coercion wrapper. :class:`.TypeCoerce` supplies the :func:`.expression.type_coerce` @@ -2694,6 +2734,10 @@ class TypeCoerce(ColumnElement): else: return self.clause + @property + def wrapped_column_expression(self): + return self.clause + class Extract(ColumnElement): """Represent a SQL EXTRACT clause, ``extract(field FROM expr)``.""" @@ -3162,7 +3206,7 @@ class CollectionAggregate(UnaryExpression): ) -class AsBoolean(UnaryExpression): +class AsBoolean(WrapsColumnExpression, UnaryExpression): def __init__(self, element, operator, negate): self.element = element self.type = type_api.BOOLEANTYPE @@ -3172,6 +3216,10 @@ class AsBoolean(UnaryExpression): self.wraps_column_expression = True self._is_implicitly_boolean = element._is_implicitly_boolean + @property + def wrapped_column_expression(self): + return self.element + def self_group(self, against=None): # type: (Optional[Any]) -> ClauseElement return self |