diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-27 18:25:57 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-27 18:25:57 -0500 |
commit | 2104d0ba2d612a26d363a3049d5e49efe4284e15 (patch) | |
tree | 94878393dfd1d689dd5173e86c575af4b44c5261 /lib/sqlalchemy/sql/elements.py | |
parent | de786a4208e621229769a8fb1f876f358dc4e70e (diff) | |
download | sqlalchemy-2104d0ba2d612a26d363a3049d5e49efe4284e15.tar.gz |
- rework the JSON expression system so that "astext" is called *after*
the indexing. this is for more natural operation.
- also add cast() to the JSON expression to complement astext. This integrates
the CAST call which will be needed frequently. Part of [ticket:2687].
- it's a little unclear how more advanced unicode attribute-access is going to go,
some quick attempts at testing yielded strange error messages from psycopg2.
- do other cross linking as mentioned in [ticket:2687].
Diffstat (limited to 'lib/sqlalchemy/sql/elements.py')
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 91ce0a090..dfebf09a8 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -80,7 +80,7 @@ def literal(value, type_=None): -def type_coerce(expr, type_): +def type_coerce(expression, type_): """Coerce the given expression into the given type, on the Python side only. @@ -116,22 +116,30 @@ def type_coerce(expr, type_): ) ) + :param expression: Column-oriented expression. + :param type_: A :class:`.TypeEngine` class or instance indicating + the type to which the CAST should apply. + + .. seealso:: + + :func:`.cast` + """ type_ = type_api.to_instance(type_) - if hasattr(expr, '__clause_element__'): - return type_coerce(expr.__clause_element__(), type_) - elif isinstance(expr, BindParameter): - bp = expr._clone() + if hasattr(expression, '__clause_element__'): + return type_coerce(expression.__clause_element__(), type_) + elif isinstance(expression, BindParameter): + bp = expression._clone() bp.type = type_ return bp - elif not isinstance(expr, Visitable): - if expr is None: + elif not isinstance(expression, Visitable): + if expression is None: return Null() else: - return literal(expr, type_=type_) + return literal(expression, type_=type_) else: - return Label(None, expr, type_=type_) + return Label(None, expression, type_=type_) @@ -1734,12 +1742,12 @@ class Cast(ColumnElement): __visit_name__ = 'cast' - def __init__(self, clause, totype, **kwargs): + def __init__(self, expression, type_): """Return a :class:`.Cast` object. Equivalent of SQL ``CAST(clause AS totype)``. - Use with a :class:`~sqlalchemy.types.TypeEngine` subclass, i.e:: + E.g.:: cast(table.c.unit_price * table.c.qty, Numeric(10,4)) @@ -1747,12 +1755,18 @@ class Cast(ColumnElement): cast(table.c.timestamp, DATE) - :class:`.Cast` is available using :func:`.cast` or alternatively - ``func.cast`` from the :data:`.func` namespace. + :param expression: Column-oriented expression. + :param type_: A :class:`.TypeEngine` class or instance indicating + the type to which the CAST should apply. + + .. seealso:: + + :func:`.type_coerce` - Python-side type coercion without emitting + CAST. """ - self.type = type_api.to_instance(totype) - self.clause = _literal_as_binds(clause, None) + self.type = type_api.to_instance(type_) + self.clause = _literal_as_binds(expression, None) if isinstance(self.clause, BindParameter) and ( self.clause.type._isnull or self.clause.type._type_affinity is self.type._type_affinity |