summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/elements.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-01-26 20:02:08 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-01-26 20:02:08 -0500
commitd20d7549fd32d867739169ac2556f3fa0157b4b1 (patch)
treee211596ff423bd72caee087ca7d08f090e022abc /lib/sqlalchemy/sql/elements.py
parentae3f2abe06af5541d19f30d716806a47c8472098 (diff)
downloadsqlalchemy-d20d7549fd32d867739169ac2556f3fa0157b4b1.tar.gz
- docs
Diffstat (limited to 'lib/sqlalchemy/sql/elements.py')
-rw-r--r--lib/sqlalchemy/sql/elements.py152
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::