diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-10-23 16:40:39 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-10-23 16:40:39 -0400 |
commit | 79c25ede440e80e15c4c789234157d0e9497349c (patch) | |
tree | e9517ef97e2b0a1ed8426b909135d21c23557772 /lib/sqlalchemy/sql/expression.py | |
parent | c01c6baf5715a13d707a4d57717f9ad1bc12027a (diff) | |
download | sqlalchemy-79c25ede440e80e15c4c789234157d0e9497349c.tar.gz |
- Added type_coerce(expr, type_) expression element.
Treats the given expression as the given type when evaluating
expressions and processing result rows, but does not
affect the generation of SQL, other than an anonymous label.
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 219e3bf14..625893a68 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -45,8 +45,8 @@ __all__ = [ 'except_', 'except_all', 'exists', 'extract', 'func', 'modifier', 'collate', 'insert', 'intersect', 'intersect_all', 'join', 'label', 'literal', 'literal_column', 'not_', 'null', 'or_', 'outparam', - 'outerjoin', 'select', 'subquery', 'table', 'text', 'tuple_', 'union', - 'union_all', 'update', ] + 'outerjoin', 'select', 'subquery', 'table', 'text', 'tuple_', 'type_coerce', + 'union', 'union_all', 'update', ] PARSE_AUTOCOMMIT = util._symbol('PARSE_AUTOCOMMIT') @@ -666,6 +666,54 @@ def tuple_(*expr): """ return _Tuple(*expr) + +def type_coerce(expr, type_): + """Coerce the given expression into the given type, on the Python side only. + + :func:`.type_coerce` is roughly similar to :func:.`cast`, except no + "CAST" expression is rendered - the given type is only applied towards + expression typing and against received result values. + + e.g.:: + + from sqlalchemy.types import TypeDecorator + import uuid + + class AsGuid(TypeDecorator): + impl = String + + def process_bind_param(self, value, dialect): + if value is not None: + return str(value) + else: + return None + + def process_result_value(self, value, dialect): + if value is not None: + return uuid.UUID(value) + else: + return None + + conn.execute( + select([type_coerce(mytable.c.ident, AsGuid)]).\\ + where( + type_coerce(mytable.c.ident, AsGuid) == + uuid.uuid3(uuid.NAMESPACE_URL, 'bar') + ) + ) + + """ + if hasattr(expr, '__clause_expr__'): + return type_coerce(expr.__clause_expr__()) + + elif not isinstance(expr, Visitable): + if expr is None: + return null() + else: + return literal(expr, type_=type_) + else: + return _Label(None, expr, type_=type_) + def label(name, obj): """Return a :class:`_Label` object for the |