summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/expression.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-10-23 16:40:39 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2010-10-23 16:40:39 -0400
commit79c25ede440e80e15c4c789234157d0e9497349c (patch)
treee9517ef97e2b0a1ed8426b909135d21c23557772 /lib/sqlalchemy/sql/expression.py
parentc01c6baf5715a13d707a4d57717f9ad1bc12027a (diff)
downloadsqlalchemy-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.py52
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