diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-26 20:02:08 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-01-26 20:02:08 -0500 |
commit | d20d7549fd32d867739169ac2556f3fa0157b4b1 (patch) | |
tree | e211596ff423bd72caee087ca7d08f090e022abc /lib/sqlalchemy/sql/elements.py | |
parent | ae3f2abe06af5541d19f30d716806a47c8472098 (diff) | |
download | sqlalchemy-d20d7549fd32d867739169ac2556f3fa0157b4b1.tar.gz |
- docs
Diffstat (limited to 'lib/sqlalchemy/sql/elements.py')
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 152 |
1 files changed, 115 insertions, 37 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 2963ef1a5..975cf2d79 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -116,44 +116,44 @@ def literal(value, type_=None): def type_coerce(expression, type_): - """Coerce the given expression into the given type, - on the Python side only. + """Associate a SQL expression with a particular type, without rendering + ``CAST``. - :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.:: - e.g.:: + from sqlalchemy import type_coerce - from sqlalchemy.types import TypeDecorator - import uuid + stmt = select([type_coerce(log_table.date_string, StringDateTime())]) - class AsGuid(TypeDecorator): - impl = String + The above construct will produce SQL that is usually otherwise unaffected + by the :func:`.type_coerce` call:: - def process_bind_param(self, value, dialect): - if value is not None: - return str(value) - else: - return None + SELECT date_string FROM log - def process_result_value(self, value, dialect): - if value is not None: - return uuid.UUID(value) - else: - return None + However, when result rows are fetched, the ``StringDateTime`` type + will be applied to result rows on behalf of the ``date_string`` column. - conn.execute( - select([type_coerce(mytable.c.ident, AsGuid)]).\\ - where( - type_coerce(mytable.c.ident, AsGuid) == - uuid.uuid3(uuid.NAMESPACE_URL, 'bar') - ) - ) + A type that features bound-value handling will also have that behavior + take effect when literal values or :func:`.bindparam` constructs are + passed to :func:`.type_coerce` as targets. + For example, if a type implements the :meth:`.TypeEngine.bind_expression` + method or :meth:`.TypeEngine.bind_processor` method or equivalent, + these functions will take effect at statement compliation/execution time + when a literal value is passed, as in:: + + # bound-value handling of MyStringType will be applied to the + # literal value "some string" + stmt = select([type_coerce("some string", MyStringType)]) + + :func:`.type_coerce` is similar to the :func:`.cast` function, + except that it does not render the ``CAST`` expression in the resulting + statement. + + :param expression: A SQL expression, such as a :class:`.ColumnElement` expression + or a Python string which will be coerced into a bound literal value. - :param expression: Column-oriented expression. :param type_: A :class:`.TypeEngine` class or instance indicating - the type to which the CAST should apply. + the type to which the the expression is coerced. .. seealso:: @@ -523,6 +523,41 @@ class ColumnElement(ClauseElement, operators.ColumnOperators): literal expressions, keywords such as ``NULL``, etc. :class:`.ColumnElement` is the ultimate base class for all such elements. + A wide variety of SQLAlchemy Core functions work at the SQL expression level, + and are intended to accept instances of :class:`.ColumnElement` as arguments. + These functions will typically document that they accept a "SQL expression" + as an argument. What this means in terms of SQLAlchemy usually refers + to an input which is either already in the form of a :class:`.ColumnElement` + object, or a value which can be **coerced** into one. The coercion + rules followed by most, but not all, SQLAlchemy Core functions with regards + to SQL expressions are as follows: + + * a literal Python value, such as a string, integer or floating + point value, boolean, datetime, ``Decimal`` object, or virtually + any other Python object, will be coerced into a "literal bound value". + This generally means that a :func:`.bindparam` will be produced + featuring the given value embedded into the construct; the resulting + :class:`.BindParameter` object is an instance of :class:`.ColumnElement`. + The Python value will ultimately be sent to the DBAPI at execution time as a + paramterized argument to the ``execute()`` or ``executemany()`` methods, + after SQLAlchemy type-specific converters (e.g. those provided by + any associated :class:`.TypeEngine` objects) are applied to the value. + + * any special object value, typically ORM-level constructs, which feature + a method called ``__clause_element__()``. The Core expression system + looks for this method when an object of otherwise unknown type is passed + to a function that is looking to coerce the argument into a :class:`.ColumnElement` + expression. The ``__clause_element__()`` method, if present, should + return a :class:`.ColumnElement` instance. The primary use of + ``__clause_element__()`` within SQLAlchemy is that of class-bound attributes + on ORM-mapped classes; a ``User`` class which contains a mapped attribute + named ``.name`` will have a method ``User.name.__clause_element__()`` + which when invoked returns the :class:`.Column` called ``name`` associated + with the mapped table. + + * The Python ``None`` value is typically interpreted as ``NULL``, which + in SQLAlchemy Core produces an instance of :func:`.null`. + A :class:`.ColumnElement` provides the ability to generate new :class:`.ColumnElement` objects using Python expressions. This means that Python operators @@ -2066,26 +2101,69 @@ def literal_column(text, type_=None): class Cast(ColumnElement): - """Represent the SQL ``CAST`` construct.""" + """Represent a ``CAST`` expression. + + :class:`.Cast` is produced using the :func:`.cast` factory function, + as in:: + + from sqlalchemy import cast, Numeric + + stmt = select([ + cast(product_table.c.unit_price, Numeric(10, 4)) + ]) + + Details on :class:`.Cast` usage is at :func:`.cast`. + + .. seealso:: + + :func:`.cast` + + """ __visit_name__ = 'cast' def __init__(self, expression, type_): - """Return a :class:`.Cast` object. + """Produce a ``CAST`` expression. - Equivalent of SQL ``CAST(clause AS totype)``. + :func:`.cast` returns an instance of :class:`.Cast`. E.g.:: - cast(table.c.unit_price * table.c.qty, Numeric(10,4)) + from sqlalchemy import cast, Numeric + + stmt = select([ + cast(product_table.c.unit_price, Numeric(10, 4)) + ]) + + The above statement will produce SQL resembling:: + + SELECT CAST(unit_price AS NUMERIC(10, 4)) FROM product + + The :func:`.cast` function performs two distinct functions when + used. The first is that it renders the ``CAST`` expression within + the resulting SQL string. The second is that it associates the given + type (e.g. :class:`.TypeEngine` class or instance) with the column + expression on the Python side, which means the expression will take + on the expression operator behavior associated with that type, + as well as the bound-value handling and result-row-handling behavior + of the type. + + .. versionchanged:: 0.9.0 :func:`.cast` now applies the given type + to the expression such that it takes effect on the bound-value, + e.g. the Python-to-database direction, in addition to the + result handling, e.g. database-to-Python, direction. - or:: + An alternative to :func:`.cast` is the :func:`.type_coerce` function. + This function performs the second task of associating an expression + with a specific type, but does not render the ``CAST`` expression + in SQL. - cast(table.c.timestamp, DATE) + :param expression: A SQL expression, such as a :class:`.ColumnElement` + expression or a Python string which will be coerced into a bound + literal value. - :param expression: Column-oriented expression. :param type_: A :class:`.TypeEngine` class or instance indicating - the type to which the CAST should apply. + the type to which the ``CAST`` should apply. .. seealso:: |