summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql.py')
-rw-r--r--lib/sqlalchemy/sql.py1612
1 files changed, 817 insertions, 795 deletions
diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py
index 2f1cd4b91..7c73f7cb7 100644
--- a/lib/sqlalchemy/sql.py
+++ b/lib/sqlalchemy/sql.py
@@ -4,46 +4,50 @@
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-"""Define the base components of SQL expression trees.
-
-All components are derived from a common base class [sqlalchemy.sql#ClauseElement].
-Common behaviors are organized based on class hierarchies, in some cases
-via mixins.
-
-All object construction from this package occurs via functions which in some
-cases will construct composite ``ClauseElement`` structures together, and
-in other cases simply return a single ``ClauseElement`` constructed directly.
-The function interface affords a more "DSL-ish" feel to constructing SQL expressions
-and also allows future class reorganizations.
-
-Even though classes are not constructed directly from the outside, most
-classes which have additional public methods are considered to be public (i.e. have no leading underscore).
-Other classes which are "semi-public" are marked with a single leading
-underscore; these classes usually have few or no public methods and
-are less guaranteed to stay the same in future releases.
-
+"""Defines the base components of SQL expression trees.
+
+
+All components are derived from a common base class
+[sqlalchemy.sql#ClauseElement]. Common behaviors are organized based
+on class hierarchies, in some cases via mixins.
+
+All object construction from this package occurs via functions which
+in some cases will construct composite ``ClauseElement`` structures
+together, and in other cases simply return a single ``ClauseElement``
+constructed directly. The function interface affords a more "DSL-ish"
+feel to constructing SQL expressions and also allows future class
+reorganizations.
+
+Even though classes are not constructed directly from the outside,
+most classes which have additional public methods are considered to be
+public (i.e. have no leading underscore). Other classes which are
+"semi-public" are marked with a single leading underscore; these
+classes usually have few or no public methods and are less guaranteed
+to stay the same in future releases.
"""
from sqlalchemy import util, exceptions, operators
from sqlalchemy import types as sqltypes
import re
-__all__ = ['Alias', 'ClauseElement', 'ClauseParameters',
- 'ClauseVisitor', 'ColumnCollection', 'ColumnElement',
- 'CompoundSelect', 'Delete', 'FromClause', 'Insert', 'Join',
- 'Select', 'Selectable', 'TableClause', 'Update', 'alias', 'and_', 'asc',
- 'between', 'bindparam', 'case', 'cast', 'column', 'delete',
- 'desc', 'distinct', 'except_', 'except_all', 'exists', 'extract', 'func', 'modifier',
- 'insert', 'intersect', 'intersect_all', 'join', 'literal',
- 'literal_column', 'not_', 'null', 'or_', 'outparam', 'outerjoin', 'select',
- 'subquery', 'table', 'text', 'union', 'union_all', 'update',]
+__all__ = [
+ 'Alias', 'ClauseElement', 'ClauseParameters',
+ 'ClauseVisitor', 'ColumnCollection', 'ColumnElement',
+ 'CompoundSelect', 'Delete', 'FromClause', 'Insert', 'Join',
+ 'Select', 'Selectable', 'TableClause', 'Update', 'alias', 'and_', 'asc',
+ 'between', 'bindparam', 'case', 'cast', 'column', 'delete',
+ 'desc', 'distinct', 'except_', 'except_all', 'exists', 'extract', 'func',
+ 'modifier',
+ 'insert', 'intersect', 'intersect_all', 'join', 'literal',
+ 'literal_column', 'not_', 'null', 'or_', 'outparam', 'outerjoin', 'select',
+ 'subquery', 'table', 'text', 'union', 'union_all', 'update', ]
BIND_PARAMS = re.compile(r'(?<![:\w\x5c]):(\w+)(?!:)', re.UNICODE)
def desc(column):
"""Return a descending ``ORDER BY`` clause element.
- E.g.::
+ e.g.::
order_by = [desc(table1.mycol)]
"""
@@ -52,7 +56,7 @@ def desc(column):
def asc(column):
"""Return an ascending ``ORDER BY`` clause element.
- E.g.::
+ e.g.::
order_by = [asc(table1.mycol)]
"""
@@ -60,22 +64,22 @@ def asc(column):
def outerjoin(left, right, onclause=None, **kwargs):
"""Return an ``OUTER JOIN`` clause element.
-
+
The returned object is an instance of [sqlalchemy.sql#Join].
- Similar functionality is also available via the ``outerjoin()`` method on any
- [sqlalchemy.sql#FromClause].
+ Similar functionality is also available via the ``outerjoin()``
+ method on any [sqlalchemy.sql#FromClause].
- left
- The left side of the join.
+ left
+ The left side of the join.
- right
- The right side of the join.
+ right
+ The right side of the join.
- onclause
- Optional criterion for the ``ON`` clause, is derived from
- foreign key relationships established between left and right
- otherwise.
+ onclause
+ Optional criterion for the ``ON`` clause, is derived from
+ foreign key relationships established between left and right
+ otherwise.
To chain joins together, use the ``join()`` or ``outerjoin()``
methods on the resulting ``Join`` object.
@@ -88,19 +92,19 @@ def join(left, right, onclause=None, **kwargs):
The returned object is an instance of [sqlalchemy.sql#Join].
- Similar functionality is also available via the ``join()`` method on any
- [sqlalchemy.sql#FromClause].
+ Similar functionality is also available via the ``join()`` method
+ on any [sqlalchemy.sql#FromClause].
- left
- The left side of the join.
+ left
+ The left side of the join.
- right
- The right side of the join.
+ right
+ The right side of the join.
- onclause
- Optional criterion for the ``ON`` clause, is derived from
- foreign key relationships established between left and right
- otherwise.
+ onclause
+ Optional criterion for the ``ON`` clause, is derived from
+ foreign key relationships established between left and right
+ otherwise.
To chain joins together, use the ``join()`` or ``outerjoin()``
methods on the resulting ``Join`` object.
@@ -111,109 +115,116 @@ def join(left, right, onclause=None, **kwargs):
def select(columns=None, whereclause=None, from_obj=[], **kwargs):
"""Returns a ``SELECT`` clause element.
- Similar functionality is also available via the ``select()`` method on any
- [sqlalchemy.sql#FromClause].
-
+ Similar functionality is also available via the ``select()``
+ method on any [sqlalchemy.sql#FromClause].
+
The returned object is an instance of [sqlalchemy.sql#Select].
- All arguments which accept ``ClauseElement`` arguments also
- accept string arguments, which will be converted as appropriate
- into either ``text()`` or ``literal_column()`` constructs.
-
- columns
- A list of ``ClauseElement`` objects, typically ``ColumnElement``
- objects or subclasses, which will form
- the columns clause of the resulting statement. For all
- members which are instances of ``Selectable``, the individual
- ``ColumnElement`` members of the ``Selectable`` will be
- added individually to the columns clause. For example, specifying
- a ``Table`` instance will result in all the contained ``Column``
- objects within to be added to the columns clause.
-
- This argument is not present on the form of ``select()`` available
- on ``Table``.
-
- whereclause
- A ``ClauseElement`` expression which will be used to form the
- ``WHERE`` clause.
-
- from_obj
- A list of ``ClauseElement`` objects which will be added to the ``FROM``
- clause of the resulting statement. Note that "from" objects
- are automatically located within the columns and whereclause
- ClauseElements. Use this parameter to explicitly specify
- "from" objects which are not automatically locatable.
- This could include ``Table`` objects that aren't otherwise
- present, or ``Join`` objects whose presence will supercede
- that of the ``Table`` objects already located in the other
- clauses.
-
- \**kwargs
- Additional parameters include:
-
- order_by
- a scalar or list of ``ClauseElement`` objects
- which will comprise the ``ORDER BY`` clause of the resulting
- select.
-
- group_by
- a list of ``ClauseElement`` objects which will comprise
- the ``GROUP BY`` clause of the resulting select.
-
- having
- a ``ClauseElement`` that will comprise the ``HAVING``
- clause of the resulting select when ``GROUP BY`` is used.
-
- use_labels=False
- when ``True``, the statement will be generated using
- labels for each column in the columns clause, which qualify
- each column with its parent table's (or aliases) name so
- that name conflicts between columns in different tables don't
- occur. The format of the label is <tablename>_<column>. The
- "c" collection of the resulting ``Select`` object will use these
- names as well for targeting column members.
-
- distinct=False
- when ``True``, applies a ``DISTINCT`` qualifier to the
- columns clause of the resulting statement.
-
- for_update=False
- when ``True``, applies ``FOR UPDATE`` to the end of the
- resulting statement. Certain database dialects also
- support alternate values for this parameter, for example
- mysql supports "read" which translates to ``LOCK IN SHARE MODE``,
- and oracle supports "nowait" which translates to
- ``FOR UPDATE NOWAIT``.
-
- bind=None
- an ``Engine`` or ``Connection`` instance to which the resulting ``Select``
- object will be bound. The ``Select`` object will otherwise
- automatically bind to whatever ``Connectable`` instances can be located
- within its contained ``ClauseElement`` members.
-
- limit=None
- a numerical value which usually compiles to a ``LIMIT`` expression
- in the resulting select. Databases that don't support ``LIMIT``
- will attempt to provide similar functionality.
-
- offset=None
- a numerical value which usually compiles to an ``OFFSET`` expression
- in the resulting select. Databases that don't support ``OFFSET``
- will attempt to provide similar functionality.
-
- scalar=False
- deprecated. use select(...).as_scalar() to create a "scalar column"
- proxy for an existing Select object.
-
- correlate=True
- indicates that this ``Select`` object should have its contained
- ``FromClause`` elements "correlated" to an enclosing ``Select``
- object. This means that any ``ClauseElement`` instance within
- the "froms" collection of this ``Select`` which is also present
- in the "froms" collection of an enclosing select will not be
- rendered in the ``FROM`` clause of this select statement.
-
+ All arguments which accept ``ClauseElement`` arguments also accept
+ string arguments, which will be converted as appropriate into
+ either ``text()`` or ``literal_column()`` constructs.
+
+ columns
+ A list of ``ClauseElement`` objects, typically ``ColumnElement``
+ objects or subclasses, which will form the columns clause of the
+ resulting statement. For all members which are instances of
+ ``Selectable``, the individual ``ColumnElement`` members of the
+ ``Selectable`` will be added individually to the columns clause.
+ For example, specifying a ``Table`` instance will result in all
+ the contained ``Column`` objects within to be added to the
+ columns clause.
+
+ This argument is not present on the form of ``select()``
+ available on ``Table``.
+
+ whereclause
+ A ``ClauseElement`` expression which will be used to form the
+ ``WHERE`` clause.
+
+ from_obj
+ A list of ``ClauseElement`` objects which will be added to the
+ ``FROM`` clause of the resulting statement. Note that "from"
+ objects are automatically located within the columns and
+ whereclause ClauseElements. Use this parameter to explicitly
+ specify "from" objects which are not automatically locatable.
+ This could include ``Table`` objects that aren't otherwise
+ present, or ``Join`` objects whose presence will supercede that
+ of the ``Table`` objects already located in the other clauses.
+
+ \**kwargs
+ Additional parameters include:
+
+ prefixes
+ a list of strings or ``ClauseElement`` objects to include
+ directly after the SELECT keyword in the generated statement,
+ for dialect-specific query features.
+
+ distinct=False
+ when ``True``, applies a ``DISTINCT`` qualifier to the columns
+ clause of the resulting statement.
+
+ use_labels=False
+ when ``True``, the statement will be generated using labels
+ for each column in the columns clause, which qualify each
+ column with its parent table's (or aliases) name so that name
+ conflicts between columns in different tables don't occur.
+ The format of the label is <tablename>_<column>. The "c"
+ collection of the resulting ``Select`` object will use these
+ names as well for targeting column members.
+
+ for_update=False
+ when ``True``, applies ``FOR UPDATE`` to the end of the
+ resulting statement. Certain database dialects also support
+ alternate values for this parameter, for example mysql
+ supports "read" which translates to ``LOCK IN SHARE MODE``,
+ and oracle supports "nowait" which translates to ``FOR UPDATE
+ NOWAIT``.
+
+ correlate=True
+ indicates that this ``Select`` object should have its
+ contained ``FromClause`` elements "correlated" to an enclosing
+ ``Select`` object. This means that any ``ClauseElement``
+ instance within the "froms" collection of this ``Select``
+ which is also present in the "froms" collection of an
+ enclosing select will not be rendered in the ``FROM`` clause
+ of this select statement.
+
+ group_by
+ a list of ``ClauseElement`` objects which will comprise the
+ ``GROUP BY`` clause of the resulting select.
+
+ having
+ a ``ClauseElement`` that will comprise the ``HAVING`` clause
+ of the resulting select when ``GROUP BY`` is used.
+
+ order_by
+ a scalar or list of ``ClauseElement`` objects which will
+ comprise the ``ORDER BY`` clause of the resulting select.
+
+ limit=None
+ a numerical value which usually compiles to a ``LIMIT``
+ expression in the resulting select. Databases that don't
+ support ``LIMIT`` will attempt to provide similar
+ functionality.
+
+ offset=None
+ a numeric value which usually compiles to an ``OFFSET``
+ expression in the resulting select. Databases that don't
+ support ``OFFSET`` will attempt to provide similar
+ functionality.
+
+ bind=None
+ an ``Engine`` or ``Connection`` instance to which the
+ resulting ``Select ` object will be bound. The ``Select``
+ object will otherwise automatically bind to whatever
+ ``Connectable`` instances can be located within its contained
+ ``ClauseElement`` members.
+
+ scalar=False
+ deprecated. Use select(...).as_scalar() to create a "scalar
+ column" proxy for an existing Select object.
"""
+
if 'scalar' in kwargs:
util.warn_deprecated('scalar option is deprecated; see docs for details')
scalar = kwargs.pop('scalar', False)
@@ -225,34 +236,35 @@ def select(columns=None, whereclause=None, from_obj=[], **kwargs):
def subquery(alias, *args, **kwargs):
"""Return an [sqlalchemy.sql#Alias] object derived from a [sqlalchemy.sql#Select].
-
- name
- alias name
- \*args, \**kwargs
- all other arguments are delivered to the [sqlalchemy.sql#select()] function.
-
+ name
+ alias name
+
+ \*args, \**kwargs
+
+ all other arguments are delivered to the [sqlalchemy.sql#select()]
+ function.
"""
-
+
return Select(*args, **kwargs).alias(alias)
def insert(table, values = None, **kwargs):
"""Return an [sqlalchemy.sql#Insert] clause element.
- Similar functionality is available via the ``insert()``
- method on [sqlalchemy.schema#Table].
+ Similar functionality is available via the ``insert()`` method on
+ [sqlalchemy.schema#Table].
- table
- The table to be inserted into.
+ table
+ The table to be inserted into.
- values
- A dictionary which specifies the column specifications of the
- ``INSERT``, and is optional. If left as None, the column
- specifications are determined from the bind parameters used
- during the compile phase of the ``INSERT`` statement. If the
- bind parameters also are None during the compile phase, then the
- column specifications will be generated from the full list of
- table columns.
+ values
+ A dictionary which specifies the column specifications of the
+ ``INSERT``, and is optional. If left as None, the column
+ specifications are determined from the bind parameters used
+ during the compile phase of the ``INSERT`` statement. If the
+ bind parameters also are None during the compile phase, then the
+ column specifications will be generated from the full list of
+ table columns.
If both `values` and compile-time bind parameters are present, the
compile-time bind parameters override the information specified
@@ -275,24 +287,24 @@ def insert(table, values = None, **kwargs):
def update(table, whereclause = None, values = None, **kwargs):
"""Return an [sqlalchemy.sql#Update] clause element.
- Similar functionality is available via the ``update()``
- method on [sqlalchemy.schema#Table].
+ Similar functionality is available via the ``update()`` method on
+ [sqlalchemy.schema#Table].
- table
- The table to be updated.
+ table
+ The table to be updated.
- whereclause
- A ``ClauseElement`` describing the ``WHERE`` condition of the
- ``UPDATE`` statement.
+ whereclause
+ A ``ClauseElement`` describing the ``WHERE`` condition of the
+ ``UPDATE`` statement.
- values
- A dictionary which specifies the ``SET`` conditions of the
- ``UPDATE``, and is optional. If left as None, the ``SET``
- conditions are determined from the bind parameters used during
- the compile phase of the ``UPDATE`` statement. If the bind
- parameters also are None during the compile phase, then the
- ``SET`` conditions will be generated from the full list of table
- columns.
+ values
+ A dictionary which specifies the ``SET`` conditions of the
+ ``UPDATE``, and is optional. If left as None, the ``SET``
+ conditions are determined from the bind parameters used during
+ the compile phase of the ``UPDATE`` statement. If the bind
+ parameters also are None during the compile phase, then the
+ ``SET`` conditions will be generated from the full list of table
+ columns.
If both `values` and compile-time bind parameters are present, the
compile-time bind parameters override the information specified
@@ -315,16 +327,15 @@ def update(table, whereclause = None, values = None, **kwargs):
def delete(table, whereclause = None, **kwargs):
"""Return a [sqlalchemy.sql#Delete] clause element.
- Similar functionality is available via the ``delete()``
- method on [sqlalchemy.schema#Table].
-
- table
- The table to be updated.
+ Similar functionality is available via the ``delete()`` method on
+ [sqlalchemy.schema#Table].
- whereclause
- A ``ClauseElement`` describing the ``WHERE`` condition of the
- ``UPDATE`` statement.
+ table
+ The table to be updated.
+ whereclause
+ A ``ClauseElement`` describing the ``WHERE`` condition of the
+ ``UPDATE`` statement.
"""
return Delete(table, whereclause, **kwargs)
@@ -332,8 +343,9 @@ def delete(table, whereclause = None, **kwargs):
def and_(*clauses):
"""Join a list of clauses together using the ``AND`` operator.
- The ``&`` operator is also overloaded on all [sqlalchemy.sql#_CompareMixin]
- subclasses to produce the same result.
+ The ``&`` operator is also overloaded on all
+ [sqlalchemy.sql#_CompareMixin] subclasses to produce the same
+ result.
"""
if len(clauses) == 1:
return clauses[0]
@@ -342,8 +354,9 @@ def and_(*clauses):
def or_(*clauses):
"""Join a list of clauses together using the ``OR`` operator.
- The ``|`` operator is also overloaded on all [sqlalchemy.sql#_CompareMixin]
- subclasses to produce the same result.
+ The ``|`` operator is also overloaded on all
+ [sqlalchemy.sql#_CompareMixin] subclasses to produce the same
+ result.
"""
if len(clauses) == 1:
@@ -353,15 +366,16 @@ def or_(*clauses):
def not_(clause):
"""Return a negation of the given clause, i.e. ``NOT(clause)``.
- The ``~`` operator is also overloaded on all [sqlalchemy.sql#_CompareMixin]
- subclasses to produce the same result.
+ The ``~`` operator is also overloaded on all
+ [sqlalchemy.sql#_CompareMixin] subclasses to produce the same
+ result.
"""
return operators.inv(clause)
def distinct(expr):
- """return a ``DISTINCT`` clause."""
-
+ """Return a ``DISTINCT`` clause."""
+
return _UnaryExpression(expr, operator=operators.distinct_op)
def between(ctest, cleft, cright):
@@ -380,18 +394,18 @@ def between(ctest, cleft, cright):
def case(whens, value=None, else_=None):
"""Produce a ``CASE`` statement.
- whens
- A sequence of pairs to be translated into "when / then" clauses.
-
- value
- Optional for simple case statements.
+ whens
+ A sequence of pairs to be translated into "when / then" clauses.
- else\_
- Optional as well, for case defaults.
+ value
+ Optional for simple case statements.
+ else\_
+ Optional as well, for case defaults.
"""
- whenlist = [ClauseList('WHEN', c, 'THEN', r, operator=None) for (c,r) in whens]
+ whenlist = [ClauseList('WHEN', c, 'THEN', r, operator=None)
+ for (c,r) in whens]
if not else_ is None:
whenlist.append(ClauseList('ELSE', else_, operator=None))
if whenlist:
@@ -425,128 +439,128 @@ def extract(field, expr):
def exists(*args, **kwargs):
"""Return an ``EXISTS`` clause as applied to a [sqlalchemy.sql#Select] object.
-
- The resulting [sqlalchemy.sql#_Exists] object can be executed by itself
- or used as a subquery within an enclosing select.
-
- \*args, \**kwargs
- all arguments are sent directly to the [sqlalchemy.sql#select()] function
- to produce a ``SELECT`` statement.
-
+
+ The resulting [sqlalchemy.sql#_Exists] object can be executed by
+ itself or used as a subquery within an enclosing select.
+
+ \*args, \**kwargs
+ all arguments are sent directly to the [sqlalchemy.sql#select()]
+ function to produce a ``SELECT`` statement.
"""
-
+
return _Exists(*args, **kwargs)
def union(*selects, **kwargs):
"""Return a ``UNION`` of multiple selectables.
-
+
The returned object is an instance of [sqlalchemy.sql#CompoundSelect].
-
- A similar ``union()`` method is available on all [sqlalchemy.sql#FromClause]
- subclasses.
-
- \*selects
- a list of [sqlalchemy.sql#Select] instances.
-
- \**kwargs
- available keyword arguments are the same as those of [sqlalchemy.sql#select()].
-
+
+ A similar ``union()`` method is available on all
+ [sqlalchemy.sql#FromClause] subclasses.
+
+ \*selects
+ a list of [sqlalchemy.sql#Select] instances.
+
+ \**kwargs
+ available keyword arguments are the same as those of
+ [sqlalchemy.sql#select()].
"""
-
+
return _compound_select('UNION', *selects, **kwargs)
def union_all(*selects, **kwargs):
"""Return a ``UNION ALL`` of multiple selectables.
-
+
The returned object is an instance of [sqlalchemy.sql#CompoundSelect].
-
- A similar ``union_all()`` method is available on all [sqlalchemy.sql#FromClause]
- subclasses.
- \*selects
- a list of [sqlalchemy.sql#Select] instances.
-
- \**kwargs
- available keyword arguments are the same as those of [sqlalchemy.sql#select()].
-
+ A similar ``union_all()`` method is available on all
+ [sqlalchemy.sql#FromClause] subclasses.
+
+ \*selects
+ a list of [sqlalchemy.sql#Select] instances.
+
+ \**kwargs
+ available keyword arguments are the same as those of
+ [sqlalchemy.sql#select()].
"""
+
return _compound_select('UNION ALL', *selects, **kwargs)
def except_(*selects, **kwargs):
"""Return an ``EXCEPT`` of multiple selectables.
-
+
The returned object is an instance of [sqlalchemy.sql#CompoundSelect].
- \*selects
- a list of [sqlalchemy.sql#Select] instances.
-
- \**kwargs
- available keyword arguments are the same as those of [sqlalchemy.sql#select()].
-
+ \*selects
+ a list of [sqlalchemy.sql#Select] instances.
+
+ \**kwargs
+ available keyword arguments are the same as those of
+ [sqlalchemy.sql#select()].
"""
return _compound_select('EXCEPT', *selects, **kwargs)
def except_all(*selects, **kwargs):
"""Return an ``EXCEPT ALL`` of multiple selectables.
-
+
The returned object is an instance of [sqlalchemy.sql#CompoundSelect].
- \*selects
- a list of [sqlalchemy.sql#Select] instances.
-
- \**kwargs
- available keyword arguments are the same as those of [sqlalchemy.sql#select()].
-
+ \*selects
+ a list of [sqlalchemy.sql#Select] instances.
+
+ \**kwargs
+ available keyword arguments are the same as those of
+ [sqlalchemy.sql#select()].
"""
return _compound_select('EXCEPT ALL', *selects, **kwargs)
def intersect(*selects, **kwargs):
"""Return an ``INTERSECT`` of multiple selectables.
-
+
The returned object is an instance of [sqlalchemy.sql#CompoundSelect].
- \*selects
- a list of [sqlalchemy.sql#Select] instances.
-
- \**kwargs
- available keyword arguments are the same as those of [sqlalchemy.sql#select()].
-
+ \*selects
+ a list of [sqlalchemy.sql#Select] instances.
+
+ \**kwargs
+ available keyword arguments are the same as those of
+ [sqlalchemy.sql#select()].
"""
return _compound_select('INTERSECT', *selects, **kwargs)
def intersect_all(*selects, **kwargs):
"""Return an ``INTERSECT ALL`` of multiple selectables.
-
+
The returned object is an instance of [sqlalchemy.sql#CompoundSelect].
- \*selects
- a list of [sqlalchemy.sql#Select] instances.
-
- \**kwargs
- available keyword arguments are the same as those of [sqlalchemy.sql#select()].
-
+ \*selects
+ a list of [sqlalchemy.sql#Select] instances.
+
+ \**kwargs
+ available keyword arguments are the same as those of
+ [sqlalchemy.sql#select()].
"""
return _compound_select('INTERSECT ALL', *selects, **kwargs)
def alias(selectable, alias=None):
"""Return an [sqlalchemy.sql#Alias] object.
-
+
An ``Alias`` represents any [sqlalchemy.sql#FromClause] with
an alternate name assigned within SQL, typically using the ``AS``
clause when generated, e.g. ``SELECT * FROM table AS aliasname``.
-
- Similar functionality is available via the ``alias()`` method
+
+ Similar functionality is available via the ``alias()`` method
available on all ``FromClause`` subclasses.
-
+
selectable
- any ``FromClause`` subclass, such as a table, select statement, etc..
-
+ any ``FromClause`` subclass, such as a table, select
+ statement, etc..
+
alias
- string name to be assigned as the alias. If ``None``, a random
- name will be generated.
-
+ string name to be assigned as the alias. If ``None``, a
+ random name will be generated.
"""
-
+
return Alias(selectable, alias=alias)
@@ -554,87 +568,80 @@ def literal(value, type_=None):
"""Return a literal clause, bound to a bind parameter.
Literal clauses are created automatically when non-
- ``ClauseElement`` objects (such as strings, ints, dates, etc.) are used in
- a comparison operation with a [sqlalchemy.sql#_CompareMixin]
- subclass, such as a ``Column`` object. Use this function
- to force the generation of a literal clause, which will
- be created as a [sqlalchemy.sql#_BindParamClause] with a bound
- value.
-
- value
- the value to be bound. can be any Python object supported by
- the underlying DBAPI, or is translatable via the given type
- argument.
-
- type\_
- an optional [sqlalchemy.types#TypeEngine] which will provide
- bind-parameter translation for this literal.
-
+ ``ClauseElement`` objects (such as strings, ints, dates, etc.) are
+ used in a comparison operation with a
+ [sqlalchemy.sql#_CompareMixin] subclass, such as a ``Column``
+ object. Use this function to force the generation of a literal
+ clause, which will be created as a
+ [sqlalchemy.sql#_BindParamClause] with a bound value.
+
+ value
+ the value to be bound. Can be any Python object supported by
+ the underlying DBAPI, or is translatable via the given type
+ argument.
+
+ type\_
+ an optional [sqlalchemy.types#TypeEngine] which will provide
+ bind-parameter translation for this literal.
"""
return _BindParamClause('literal', value, type_=type_, unique=True)
def label(name, obj):
"""Return a [sqlalchemy.sql#_Label] object for the given [sqlalchemy.sql#ColumnElement].
-
- A label changes the name of an element in the columns clause
- of a ``SELECT`` statement, typically via the ``AS`` SQL keyword.
-
- This functionality is more conveniently available via
- the ``label()`` method on ``ColumnElement``.
-
- name
- label name
-
- obj
- a ``ColumnElement``.
-
+
+ A label changes the name of an element in the columns clause of a
+ ``SELECT`` statement, typically via the ``AS`` SQL keyword.
+
+ This functionality is more conveniently available via the
+ ``label()`` method on ``ColumnElement``.
+
+ name
+ label name
+
+ obj
+ a ``ColumnElement``.
"""
return _Label(name, obj)
def column(text, type_=None):
- """Return a textual column clause, as would be in the columns
- clause of a ``SELECT`` statement.
-
+ """Return a textual column clause, as would be in the columns clause of a ``SELECT`` statement.
+
The object returned is an instance of [sqlalchemy.sql#_ColumnClause],
which represents the "syntactical" portion of the schema-level
[sqlalchemy.schema#Column] object.
-
- text
- the name of the column. Quoting rules will be applied to
- the clause like any other column name. For textual column
- constructs that are not to be quoted, use the [sqlalchemy.sql#literal_column()]
- function.
-
- type\_
- an optional [sqlalchemy.types#TypeEngine] object which will provide
- result-set translation for this column.
-
+
+ text
+ the name of the column. Quoting rules will be applied to the
+ clause like any other column name. For textual column
+ constructs that are not to be quoted, use the
+ [sqlalchemy.sql#literal_column()] function.
+
+ type\_
+ an optional [sqlalchemy.types#TypeEngine] object which will
+ provide result-set translation for this column.
+
"""
return _ColumnClause(text, type_=type_)
def literal_column(text, type_=None):
- """Return a textual column clause, as would be in the columns
- clause of a ``SELECT`` statement.
-
+ """Return a textual column clause, as would be in the columns clause of a ``SELECT`` statement.
+
The object returned is an instance of [sqlalchemy.sql#_ColumnClause],
which represents the "syntactical" portion of the schema-level
[sqlalchemy.schema#Column] object.
-
-
- text
- the name of the column. Quoting rules will not be applied
- to the column. For textual column
- constructs that should be quoted like any other column
- construct, use the [sqlalchemy.sql#column()]
- function.
-
- type
- an optional [sqlalchemy.types#TypeEngine] object which will provide
- result-set translation for this column.
-
+
+ text
+ the name of the column. Quoting rules will not be applied to
+ the column. For textual column constructs that should be quoted
+ like any other column construct, use the
+ [sqlalchemy.sql#column()] function.
+
+ type
+ an optional [sqlalchemy.types#TypeEngine] object which will
+ provide result-set translation for this column.
"""
return _ColumnClause(text, type_=type_, is_literal=True)
@@ -642,8 +649,8 @@ def literal_column(text, type_=None):
def table(name, *columns):
"""Return a [sqlalchemy.sql#Table] object.
- This is a primitive version of the [sqlalchemy.schema#Table] object, which
- is a subclass of this object.
+ This is a primitive version of the [sqlalchemy.schema#Table] object,
+ which is a subclass of this object.
"""
return TableClause(name, *columns)
@@ -651,22 +658,23 @@ def table(name, *columns):
def bindparam(key, value=None, type_=None, shortname=None, unique=False):
"""Create a bind parameter clause with the given key.
- value
- a default value for this bind parameter. a bindparam with a value
- is called a ``value-based bindparam``.
+ value
+ a default value for this bind parameter. a bindparam with a
+ value is called a ``value-based bindparam``.
- shortname
- an ``alias`` for this bind parameter. usually used to alias the ``key`` and
- ``label`` of a column, i.e. ``somecolname`` and ``sometable_somecolname``
+ shortname
+ an ``alias`` for this bind parameter. usually used to alias the
+ ``key`` nd ``label`` of a column, i.e. ``somecolname`` and
+ ``sometable_somecolname``
- type
- a sqlalchemy.types.TypeEngine object indicating the type of this bind param, will
- invoke type-specific bind parameter processing
+ type
+ a sqlalchemy.types.TypeEngine object indicating the type of this
+ bind param, will invoke type-specific bind parameter processing
- unique
- if True, bind params sharing the same name will have their underlying ``key`` modified
- to a uniquely generated name. mostly useful with value-based bind params.
-
+ unique
+ if True, bind params sharing the same name will have their
+ underlying ``key`` modified to a uniquely generated name.
+ mostly useful with value-based bind params.
"""
if isinstance(key, _ColumnClause):
@@ -675,16 +683,16 @@ def bindparam(key, value=None, type_=None, shortname=None, unique=False):
return _BindParamClause(key, value, type_=type_, shortname=shortname, unique=unique)
def outparam(key, type_=None):
- """create an 'OUT' parameter for usage in functions (stored procedures), for databases
- whith support them.
-
- The ``outparam`` can be used like a regular function parameter. The "output" value will
- be available from the [sqlalchemy.engine#ResultProxy] object via its ``out_parameters``
+ """Create an 'OUT' parameter for usage in functions (stored procedures), for databases which support them.
+
+ The ``outparam`` can be used like a regular function parameter.
+ The "output" value will be available from the
+ [sqlalchemy.engine#ResultProxy] object via its ``out_parameters``
attribute, which returns a dictionary containing the values.
"""
-
+
return _BindParamClause(key, None, type_=type_, unique=False, isoutparam=True)
-
+
def text(text, bind=None, *args, **kwargs):
"""Create literal text to be inserted into a query.
@@ -695,28 +703,27 @@ def text(text, bind=None, *args, **kwargs):
outside of other ``ClauseElement`` objects, or optionally wherever
plain text is to be used.
- text
- The text of the SQL statement to be created. use ``:<param>``
- to specify bind parameters; they will be compiled to their
- engine-specific format.
-
- bind
- An optional connection or engine to be used for this text query.
-
- bindparams
- A list of ``bindparam()`` instances which can be used to define
- the types and/or initial values for the bind parameters within
- the textual statement; the keynames of the bindparams must match
- those within the text of the statement. The types will be used
- for pre-processing on bind values.
-
- typemap
- A dictionary mapping the names of columns represented in the
- ``SELECT`` clause of the textual statement to type objects,
- which will be used to perform post-processing on columns within
- the result set (for textual statements that produce result
- sets).
-
+ text
+ the text of the SQL statement to be created. use ``:<param>``
+ to specify bind parameters; they will be compiled to their
+ engine-specific format.
+
+ bind
+ an optional connection or engine to be used for this text query.
+
+ bindparams
+ a list of ``bindparam()`` instances which can be used to define
+ the types and/or initial values for the bind parameters within
+ the textual statement; the keynames of the bindparams must match
+ those within the text of the statement. The types will be used
+ for pre-processing on bind values.
+
+ typemap
+ a dictionary mapping the names of columns represented in the
+ ``SELECT`` clause of the textual statement to type objects,
+ which will be used to perform post-processing on columns within
+ the result set (for textual statements that produce result
+ sets).
"""
return _TextClause(text, bind=bind, *args, **kwargs)
@@ -740,7 +747,7 @@ class _FunctionGenerator(object):
return self.__dict__[name]
except KeyError:
raise AttributeError(name)
-
+
elif name.startswith('_'):
name = name[0:-1]
f = _FunctionGenerator(**self.opts)
@@ -757,7 +764,7 @@ func = _FunctionGenerator()
# TODO: use UnaryExpression for this instead ?
modifier = _FunctionGenerator(group=False)
-
+
def _compound_select(keyword, *selects, **kwargs):
return CompoundSelect(keyword, *selects, **kwargs)
@@ -779,7 +786,7 @@ def _literal_as_column(element):
return literal_column(str(element))
else:
return element
-
+
def _literal_as_binds(element, name='literal', type_=None):
if isinstance(element, Operators):
return element.expression_element()
@@ -798,17 +805,19 @@ def _selectable(element):
return element
else:
raise exceptions.ArgumentError("Object '%s' is not a Selectable and does not implement `__selectable__()`" % repr(element))
-
+
def is_column(col):
+ """True if ``col`` is an instance of ``ColumnElement``."""
return isinstance(col, ColumnElement)
class ClauseParameters(object):
"""Represent a dictionary/iterator of bind parameter key names/values.
- Tracks the original [sqlalchemy.sql#_BindParamClause] objects as well as the
- keys/position of each parameter, and can return parameters as a
- dictionary or a list. Will process parameter values according to
- the ``TypeEngine`` objects present in the ``_BindParamClause`` instances.
+ Tracks the original [sqlalchemy.sql#_BindParamClause] objects
+ as well as the keys/position of each parameter, and can return
+ parameters as a dictionary or a list. Will process parameter
+ values according to the ``TypeEngine`` objects present in the
+ ``_BindParamClause`` instances.
"""
def __init__(self, dialect, positional=None):
@@ -821,7 +830,7 @@ class ClauseParameters(object):
def set_parameter(self, bindparam, value, name):
self.__binds[name] = [bindparam, name, value]
-
+
def get_original(self, key):
return self.__binds[key][2]
@@ -831,34 +840,34 @@ class ClauseParameters(object):
def get_processors(self):
"""return a dictionary of bind 'processing' functions"""
return dict([
- (key, value) for key, value in
+ (key, value) for key, value in
[(
key,
self.__binds[key][0].bind_processor(self.dialect)
) for key in self.__binds]
if value is not None
])
-
+
def get_processed(self, key, processors):
return key in processors and processors[key](self.__binds[key][2]) or self.__binds[key][2]
-
+
def keys(self):
return self.__binds.keys()
def __iter__(self):
return iter(self.keys())
-
+
def __getitem__(self, key):
(bind, name, value) = self.__binds[key]
processor = bind.bind_processor(self.dialect)
return processor is not None and processor(value) or value
-
+
def __contains__(self, key):
return key in self.__binds
-
+
def set_value(self, key, value):
self.__binds[key][2] = value
-
+
def get_original_dict(self):
return dict([(name, value) for (b, name, value) in self.__binds.values()])
@@ -867,7 +876,7 @@ class ClauseParameters(object):
return processors[key](self.__binds[key][2])
else:
return self.__binds[key][2]
-
+
def get_raw_list(self, processors):
return [self.__get_processed(key, processors) for key in self.positional]
@@ -893,32 +902,29 @@ class ClauseParameters(object):
return self.__class__.__name__ + ":" + repr(self.get_original_dict())
class ClauseVisitor(object):
- """A class that knows how to traverse and visit
- ``ClauseElements``.
-
- Calls visit_XXX() methods dynamically generated for each particualr
- ``ClauseElement`` subclass encountered. Traversal of a
- hierarchy of ``ClauseElements`` is achieved via the
- ``traverse()`` method, which is passed the lead
- ``ClauseElement``.
-
- By default, ``ClauseVisitor`` traverses all elements
- fully. Options can be specified at the class level via the
- ``__traverse_options__`` dictionary which will be passed
- to the ``get_children()`` method of each ``ClauseElement``;
- these options can indicate modifications to the set of
- elements returned, such as to not return column collections
- (column_collections=False) or to return Schema-level items
- (schema_visitor=True).
-
+ """A class that knows how to traverse and visit ``ClauseElements``.
+
+ Calls visit_XXX() methods dynamically generated for each
+ particualr ``ClauseElement`` subclass encountered. Traversal of a
+ hierarchy of ``ClauseElements`` is achieved via the ``traverse()``
+ method, which is passed the lead ``ClauseElement``.
+
+ By default, ``ClauseVisitor`` traverses all elements fully.
+ Options can be specified at the class level via the
+ ``__traverse_options__`` dictionary which will be passed to the
+ ``get_children()`` method of each ``ClauseElement``; these options
+ can indicate modifications to the set of elements returned, such
+ as to not return column collections (column_collections=False) or
+ to return Schema-level items (schema_visitor=True).
+
``ClauseVisitor`` also supports a simultaneous copy-and-traverse
operation, which will produce a copy of a given ``ClauseElement``
- structure while at the same time allowing ``ClauseVisitor`` subclasses
- to modify the new structure in-place.
-
+ structure while at the same time allowing ``ClauseVisitor``
+ subclasses to modify the new structure in-place.
"""
+
__traverse_options__ = {}
-
+
def traverse_single(self, obj, **kwargs):
meth = getattr(self, "visit_%s" % obj.__visit_name__, None)
if meth:
@@ -934,11 +940,11 @@ class ClauseVisitor(object):
traversal.insert(0, t)
for c in t.get_children(**self.__traverse_options__):
stack.append(c)
-
+
def traverse(self, obj, stop_on=None, clone=False):
if clone:
obj = obj._clone()
-
+
stack = [obj]
traversal = []
while len(stack) > 0:
@@ -960,8 +966,10 @@ class ClauseVisitor(object):
def chain(self, visitor):
"""'chain' an additional ClauseVisitor onto this ClauseVisitor.
-
- the chained visitor will receive all visit events after this one."""
+
+ The chained visitor will receive all visit events after this one.
+ """
+
tail = self
while getattr(tail, '_next', None) is not None:
tail = tail._next
@@ -969,16 +977,19 @@ class ClauseVisitor(object):
return self
class NoColumnVisitor(ClauseVisitor):
- """a ClauseVisitor that will not traverse the exported Column
- collections on Table, Alias, Select, and CompoundSelect objects
- (i.e. their 'columns' or 'c' attribute).
-
- this is useful because most traversals don't need those columns, or
- in the case of ANSICompiler it traverses them explicitly; so
- skipping their traversal here greatly cuts down on method call overhead.
+ """A ClauseVisitor that will not traverse exported column collections.
+
+ Will not traverse the exported Column collections on Table, Alias,
+ Select, and CompoundSelect objects (i.e. their 'columns' or 'c'
+ attribute).
+
+ This is useful because most traversals don't need those columns,
+ or in the case of ANSICompiler it traverses them explicitly; so
+ skipping their traversal here greatly cuts down on method call
+ overhead.
"""
-
- __traverse_options__ = {'column_collections':False}
+
+ __traverse_options__ = {'column_collections': False}
class _FigureVisitName(type):
@@ -989,20 +1000,19 @@ class _FigureVisitName(type):
x = re.sub(r'(?!^)[A-Z]', lambda m:'_'+m.group(0).lower(), x)
cls.__visit_name__ = x.lower()
super(_FigureVisitName, cls).__init__(clsname, bases, dict)
-
+
class ClauseElement(object):
- """Base class for elements of a programmatically constructed SQL
- expression.
- """
+ """Base class for elements of a programmatically constructed SQL expression."""
__metaclass__ = _FigureVisitName
-
+
def _clone(self):
- """create a shallow copy of this ClauseElement.
-
- This method may be used by a generative API.
- Its also used as part of the "deep" copy afforded
- by a traversal that combines the _copy_internals()
- method."""
+ """Create a shallow copy of this ClauseElement.
+
+ This method may be used by a generative API. Its also used as
+ part of the "deep" copy afforded by a traversal that combines
+ the _copy_internals() method.
+ """
+
c = self.__class__.__new__(self.__class__)
c.__dict__ = self.__dict__.copy()
return c
@@ -1017,41 +1027,40 @@ class ClauseElement(object):
raise NotImplementedError(repr(self))
def _hide_froms(self, **modifiers):
- """Return a list of ``FROM`` clause elements which this
- ``ClauseElement`` replaces.
- """
+ """Return a list of ``FROM`` clause elements which this ``ClauseElement`` replaces."""
return []
def unique_params(self, *optionaldict, **kwargs):
- """same functionality as ``params()``, except adds `unique=True` to affected
- bind parameters so that multiple statements can be used.
+ """Return a copy with ``bindparam()`` elments replaced.
+
+ Same functionality as ``params()``, except adds `unique=True`
+ to affected bind parameters so that multiple statements can be
+ used.
"""
-
+
return self._params(True, optionaldict, kwargs)
def params(self, *optionaldict, **kwargs):
- """return a copy of this ClauseElement, with ``bindparam()`` elements
- replaced with values taken from the given dictionary.
-
- e.g.::
-
- >>> clause = column('x') + bindparam('foo')
- >>> print clause.compile().params
- {'foo':None}
-
- >>> print clause.params({'foo':7}).compile().params
- {'foo':7}
-
+ """Return a copy with ``bindparam()`` elments replaced.
+
+ Returns a copy of this ClauseElement with ``bindparam()``
+ elements replaced with values taken from the given dictionary::
+
+ >>> clause = column('x') + bindparam('foo')
+ >>> print clause.compile().params
+ {'foo':None}
+ >>> print clause.params({'foo':7}).compile().params
+ {'foo':7}
"""
-
+
return self._params(False, optionaldict, kwargs)
-
+
def _params(self, unique, optionaldict, kwargs):
if len(optionaldict) == 1:
kwargs.update(optionaldict[0])
elif len(optionaldict) > 1:
raise exceptions.ArgumentError("params() takes zero or one positional dictionary argument")
-
+
class Vis(ClauseVisitor):
def visit_bindparam(self, bind):
if bind.key in kwargs:
@@ -1059,7 +1068,7 @@ class ClauseElement(object):
if unique:
bind.unique=True
return Vis().traverse(self, clone=True)
-
+
def compare(self, other):
"""Compare this ClauseElement to the given ClauseElement.
@@ -1070,32 +1079,32 @@ class ClauseElement(object):
return self is other
def _copy_internals(self):
- """reassign internal elements to be clones of themselves.
-
- called during a copy-and-traverse operation on newly
- shallow-copied elements to create a deep copy."""
-
+ """Reassign internal elements to be clones of themselves.
+
+ Called during a copy-and-traverse operation on newly
+ shallow-copied elements to create a deep copy.
+ """
+
pass
-
+
def get_children(self, **kwargs):
- """return immediate child elements of this ``ClauseElement``.
-
- this is used for visit traversal.
-
- \**kwargs may contain flags that change the collection
- that is returned, for example to return a subset of items
- in order to cut down on larger traversals, or to return
- child items from a different context (such as schema-level
- collections instead of clause-level)."""
+ """Return immediate child elements of this ``ClauseElement``.
+
+ This is used for visit traversal.
+
+ \**kwargs may contain flags that change the collection that is
+ returned, for example to return a subset of items in order to
+ cut down on larger traversals, or to return child items from a
+ different context (such as schema-level collections instead of
+ clause-level).
+ """
return []
-
+
def self_group(self, against=None):
return self
def supports_execution(self):
- """Return True if this clause element represents a complete
- executable statement.
- """
+ """Return True if this clause element represents a complete executable statement."""
return False
@@ -1120,7 +1129,7 @@ class ClauseElement(object):
return engine
else:
return None
-
+
bind = property(lambda s:s._find_engine(), doc="""Returns the Engine or Connection to which this ClauseElement is bound, or None if none found.""")
def execute(self, *multiparams, **params):
@@ -1133,9 +1142,7 @@ class ClauseElement(object):
return self.compile(bind=self.bind, parameters=compile_params).execute(*multiparams, **params)
def scalar(self, *multiparams, **params):
- """Compile and execute this ``ClauseElement``, returning the
- result's scalar representation.
- """
+ """Compile and execute this ``ClauseElement``, returning the result's scalar representation."""
return self.execute(*multiparams, **params).scalar()
@@ -1144,8 +1151,9 @@ class ClauseElement(object):
Uses the given ``Compiler``, or the given ``AbstractDialect``
or ``Engine`` to create a ``Compiler``. If no `compiler`
- arguments are given, tries to use the underlying ``Engine`` this
- ``ClauseElement`` is bound to to create a ``Compiler``, if any.
+ arguments are given, tries to use the underlying ``Engine``
+ this ``ClauseElement`` is bound to to create a ``Compiler``,
+ if any.
Finally, if there is no bound ``Engine``, uses an
``ANSIDialect`` to create a default ``Compiler``.
@@ -1218,7 +1226,8 @@ class Operators(object):
raise NotImplementedError()
class ColumnOperators(Operators):
- """defines comparison and math operations"""
+ """Defines comparison and math operations."""
+
def __lt__(self, other):
return self.operate(operators.lt, other)
@@ -1239,25 +1248,25 @@ class ColumnOperators(Operators):
def concat(self, other):
return self.operate(operators.concat_op, other)
-
+
def like(self, other):
return self.operate(operators.like_op, other)
-
+
def in_(self, *other):
return self.operate(operators.in_op, other)
-
+
def startswith(self, other):
return self.operate(operators.startswith_op, other)
def endswith(self, other):
return self.operate(operators.endswith_op, other)
-
+
def desc(self):
return self.operate(operators.desc_op)
-
+
def asc(self):
return self.operate(operators.asc_op)
-
+
def __radd__(self, other):
return self.reverse_operate(operators.add, other)
@@ -1275,7 +1284,7 @@ class ColumnOperators(Operators):
def distinct(self):
return self.operate(operators.distinct_op)
-
+
def __add__(self, other):
return self.operate(operators.add, other)
@@ -1294,8 +1303,9 @@ class ColumnOperators(Operators):
def __truediv__(self, other):
return self.operate(operators.truediv, other)
-# precedence ordering for common operators. if an operator is not present in this list,
-# it will be parenthesized when grouped against other operators
+# precedence ordering for common operators. if an operator is not
+# present in this list, it will be parenthesized when grouped against
+# other operators
_smallest = object()
_largest = object()
@@ -1346,21 +1356,18 @@ class _CompareMixin(ColumnOperators):
raise exceptions.ArgumentError("Only '='/'!=' operators can be used with NULL")
else:
obj = self._check_literal(obj)
-
-
return _BinaryExpression(self.expression_element(), obj, op, type_=sqltypes.Boolean, negate=negate)
def __operate(self, op, obj):
obj = self._check_literal(obj)
type_ = self._compare_type(obj)
-
- # TODO: generalize operator overloading like this out into the types module
+
+ # TODO: generalize operator overloading like this out into the
+ # types module
if op == operators.add and isinstance(type_, (sqltypes.Concatenable)):
op = operators.concat_op
-
return _BinaryExpression(self.expression_element(), obj, op, type_=type_)
-
operators = {
operators.add : (__operate,),
operators.mul : (__operate,),
@@ -1380,13 +1387,13 @@ class _CompareMixin(ColumnOperators):
def operate(self, op, *other):
o = _CompareMixin.operators[op]
return o[0](self, op, other[0], *o[1:])
-
+
def reverse_operate(self, op, other):
return self._bind_param(other).operate(op, self)
def in_(self, *other):
return self._in_impl(operators.in_op, operators.notin_op, *other)
-
+
def _in_impl(self, op, negate_op, *other):
if len(other) == 0:
return _Grouping(case([(self.__eq__(None), text('NULL'))], else_=text('0')).__eq__(text('1')))
@@ -1409,14 +1416,14 @@ class _CompareMixin(ColumnOperators):
return self.__compare(op, ClauseList(*args).self_group(against=op), negate=negate_op)
def startswith(self, other):
- """produce the clause ``LIKE '<other>%'``"""
+ """Produce the clause ``LIKE '<other>%'``"""
perc = isinstance(other,(str,unicode)) and '%' or literal('%',type_= sqltypes.String)
return self.__compare(operators.like_op, other + perc)
def endswith(self, other):
- """produce the clause ``LIKE '%<other>'``"""
-
+ """Produce the clause ``LIKE '%<other>'``"""
+
if isinstance(other,(str,unicode)): po = '%' + other
else:
po = literal('%', type_=sqltypes.String) + other
@@ -1424,44 +1431,43 @@ class _CompareMixin(ColumnOperators):
return self.__compare(operators.like_op, po)
def label(self, name):
- """produce a column label, i.e. ``<columnname> AS <name>``"""
+ """Produce a column label, i.e. ``<columnname> AS <name>``"""
return _Label(name, self, self.type)
-
+
def desc(self):
- """produce a DESC clause, i.e. ``<columnname> DESC``"""
-
+ """Produce a DESC clause, i.e. ``<columnname> DESC``"""
+
return desc(self)
-
+
def asc(self):
- """produce a ASC clause, i.e. ``<columnname> ASC``"""
-
+ """Produce a ASC clause, i.e. ``<columnname> ASC``"""
+
return asc(self)
-
+
def distinct(self):
- """produce a DISTINCT clause, i.e. ``DISTINCT <columnname>``"""
+ """Produce a DISTINCT clause, i.e. ``DISTINCT <columnname>``"""
return _UnaryExpression(self, operator=operators.distinct_op)
def between(self, cleft, cright):
- """produce a BETWEEN clause, i.e. ``<column> BETWEEN <cleft> AND <cright>``"""
+ """Produce a BETWEEN clause, i.e. ``<column> BETWEEN <cleft> AND <cright>``"""
return _BinaryExpression(self, ClauseList(self._check_literal(cleft), self._check_literal(cright), operator=operators.and_, group=False), operators.between_op)
def op(self, operator):
"""produce a generic operator function.
-
- e.g.
-
- somecolumn.op("*")(5)
-
- produces
-
- somecolumn * 5
-
+
+ e.g.::
+
+ somecolumn.op("*")(5)
+
+ produces::
+
+ somecolumn * 5
+
operator
- a string which will be output as the infix operator
- between this ``ClauseElement`` and the expression
- passed to the generated function.
-
+ a string which will be output as the infix operator between
+ this ``ClauseElement`` and the expression passed to the
+ generated function.
"""
return lambda other: self.__operate(operator, other)
@@ -1475,7 +1481,7 @@ class _CompareMixin(ColumnOperators):
return self._bind_param(other)
else:
return other
-
+
def clause_element(self):
"""Allow ``_CompareMixins`` to return the underlying ``ClauseElement``, for non-``ClauseElement`` ``_CompareMixins``."""
return self
@@ -1496,13 +1502,12 @@ class _CompareMixin(ColumnOperators):
class Selectable(ClauseElement):
"""Represent a column list-holding object.
-
- this is the common base class of [sqlalchemy.sql#ColumnElement]
- and [sqlalchemy.sql#FromClause]. The reason ``ColumnElement``
- is marked as a "list-holding" object is so that it can be treated
- similarly to ``FromClause`` in column-selection scenarios; it
+
+ This is the common base class of [sqlalchemy.sql#ColumnElement]
+ and [sqlalchemy.sql#FromClause]. The reason ``ColumnElement`` is
+ marked as a "list-holding" object is so that it can be treated
+ similarly to ``FromClause`` in column-selection scenarios; it
contains a list of columns consisting of itself.
-
"""
columns = util.NotImplProperty("""a [sqlalchemy.sql#ColumnCollection] containing ``ColumnElement`` instances.""")
@@ -1511,23 +1516,22 @@ class Selectable(ClauseElement):
return select([self], whereclauses, **params)
class ColumnElement(ClauseElement, _CompareMixin):
- """Represent an element that is useable within the
- "column clause" portion of a ``SELECT`` statement.
-
- This includes columns associated with tables, aliases,
- and subqueries, expressions, function calls, SQL keywords
- such as ``NULL``, literals, etc. ``ColumnElement`` is the
- ultimate base class for all such elements.
+ """Represent an element that is usable within the "column clause" portion of a ``SELECT`` statement.
+
+ This includes columns associated with tables, aliases, and
+ subqueries, expressions, function calls, SQL keywords such as
+ ``NULL``, literals, etc. ``ColumnElement`` is the ultimate base
+ class for all such elements.
``ColumnElement`` supports the ability to be a *proxy* element,
which indicates that the ``ColumnElement`` may be associated with
- a ``Selectable`` which was derived from another ``Selectable``.
- An example of a "derived" ``Selectable`` is an ``Alias`` of
- a ``Table``.
-
- a ``ColumnElement``, by subclassing the ``_CompareMixin`` mixin
- class, provides the ability to generate new ``ClauseElement``
- objects using Python expressions. See the ``_CompareMixin``
+ a ``Selectable`` which was derived from another ``Selectable``.
+ An example of a "derived" ``Selectable`` is an ``Alias`` of a
+ ``Table``.
+
+ A ``ColumnElement``, by subclassing the ``_CompareMixin`` mixin
+ class, provides the ability to generate new ``ClauseElement``
+ objects using Python expressions. See the ``_CompareMixin``
docstring for more details.
"""
@@ -1562,7 +1566,7 @@ class ColumnElement(ClauseElement, _CompareMixin):
if len(s) == 0:
s.add(self)
self.__orig_set = s
-
+
orig_set = property(_get_orig_set, _set_orig_set,
doc=\
"""A Set containing TableClause-bound, non-proxied ColumnElements
@@ -1570,10 +1574,9 @@ class ColumnElement(ClauseElement, _CompareMixin):
for a column proxied from a Union (i.e. CompoundSelect), this
set will be just one element.
""")
-
+
def shares_lineage(self, othercolumn):
- """Return True if the given ``ColumnElement`` has a common
- ancestor to this ``ColumnElement``.
+ """Return True if the given ``ColumnElement`` has a common ancestor to this ``ColumnElement``.
"""
for c in self.orig_set:
@@ -1581,7 +1584,7 @@ class ColumnElement(ClauseElement, _CompareMixin):
return True
else:
return False
-
+
def _make_proxy(self, selectable, name=None):
"""Create a new ``ColumnElement`` representing this
``ColumnElement`` as it appears in the select list of a
@@ -1613,7 +1616,7 @@ class ColumnCollection(util.OrderedProperties):
def __str__(self):
return repr([str(c) for c in self])
-
+
def add(self, column):
"""Add a column to this collection.
@@ -1628,14 +1631,14 @@ class ColumnCollection(util.OrderedProperties):
if other.name == other.key:
del self[other.name]
self[column.key] = column
-
+
def remove(self, column):
del self[column.key]
-
+
def extend(self, iter):
for c in iter:
self.add(c)
-
+
def __eq__(self, other):
l = []
for c in other:
@@ -1648,7 +1651,7 @@ class ColumnCollection(util.OrderedProperties):
if not isinstance(other, basestring):
raise exceptions.ArgumentError("__contains__ requires a string argument")
return util.OrderedProperties.__contains__(self, other)
-
+
def contains_column(self, col):
# have to use a Set here, because it will compare the identity
# of the column, not just using "==" for comparison which will always return a
@@ -1658,7 +1661,7 @@ class ColumnCollection(util.OrderedProperties):
class ColumnSet(util.OrderedSet):
def contains_column(self, col):
return col in self
-
+
def extend(self, cols):
for col in cols:
self.add(col)
@@ -1673,14 +1676,12 @@ class ColumnSet(util.OrderedSet):
if c.shares_lineage(local):
l.append(c==local)
return and_(*l)
-
+
class FromClause(Selectable):
- """Represent an element that can be used within the ``FROM``
- clause of a ``SELECT`` statement.
- """
+ """Represent an element that can be used within the ``FROM`` clause of a ``SELECT`` statement."""
__visit_name__ = 'fromclause'
-
+
def __init__(self, name=None):
self.name = name
@@ -1706,7 +1707,7 @@ class FromClause(Selectable):
def alias(self, name=None):
return Alias(self, name)
-
+
def named_with_column(self):
"""True if the name of this FromClause may be prepended to a
column in a generated SQL statement.
@@ -1733,47 +1734,45 @@ class FromClause(Selectable):
return ret
def is_derived_from(self, fromclause):
- """return True if this FromClause is 'derived' from the given FromClause.
-
- An example would be an Alias of a Table is derived from that Table."""
-
+ """Return True if this FromClause is 'derived' from the given FromClause.
+
+ An example would be an Alias of a Table is derived from that Table.
+ """
+
return False
-
+
def replace_selectable(self, old, alias):
- """replace all occurences of FromClause 'old' with the given Alias object, returning a
- copy of this ``FromClause``."""
-
+ """replace all occurences of FromClause 'old' with the given Alias object, returning a copy of this ``FromClause``."""
+
from sqlalchemy import sql_util
return sql_util.ClauseAdapter(alias).traverse(self, clone=True)
-
+
def corresponding_column(self, column, raiseerr=True, keys_ok=False, require_embedded=False):
- """Given a ``ColumnElement``, return the exported
- ``ColumnElement`` object from this ``Selectable`` which
- corresponds to that original ``Column`` via a common
- anscestor column.
-
+ """Given a ``ColumnElement``, return the exported ``ColumnElement``
+ object from this ``Selectable`` which corresponds to that
+ original ``Column`` via a common anscestor column.
+
column
the target ``ColumnElement`` to be matched
-
+
raiseerr
- if True, raise an error if the given ``ColumnElement``
- could not be matched. if False, non-matches will
- return None.
-
+ if True, raise an error if the given ``ColumnElement`` could
+ not be matched. if False, non-matches will return None.
+
keys_ok
- if the ``ColumnElement`` cannot be matched, attempt to
- match based on the string "key" property of the column
- alone. This makes the search much more liberal.
-
+ if the ``ColumnElement`` cannot be matched, attempt to match
+ based on the string "key" property of the column alone. This
+ makes the search much more liberal.
+
require_embedded
only return corresponding columns for the given
``ColumnElement``, if the given ``ColumnElement`` is
actually present within a sub-element of this
- ``FromClause``. Normally the column will match if
- it merely shares a common anscestor with one of
- the exported columns of this ``FromClause``.
+ ``FromClause``. Normally the column will match if it merely
+ shares a common anscestor with one of the exported columns
+ of this ``FromClause``.
"""
-
+
if self.c.contains_column(column):
return column
@@ -1806,10 +1805,11 @@ class FromClause(Selectable):
return getattr(self, name)
def _clone_from_clause(self):
- # delete all the "generated" collections of columns for a newly cloned FromClause,
- # so that they will be re-derived from the item.
- # this is because FromClause subclasses, when cloned, need to reestablish new "proxied"
- # columns that are linked to the new item
+ # delete all the "generated" collections of columns for a
+ # newly cloned FromClause, so that they will be re-derived
+ # from the item. this is because FromClause subclasses, when
+ # cloned, need to reestablish new "proxied" columns that are
+ # linked to the new item
for attr in ('_columns', '_primary_key' '_foreign_keys', '_orig_cols', '_oid_column'):
if hasattr(self, attr):
delattr(self, attr)
@@ -1851,17 +1851,19 @@ class FromClause(Selectable):
cp = self._proxy_column(co)
for ci in cp.orig_set:
cx = self._orig_cols.get(ci)
- # TODO: the '=' thing here relates to the order of columns as they are placed in the
- # "columns" collection of a CompositeSelect, illustrated in test/sql/selectable.SelectableTest.testunion
- # make this relationship less brittle
+ # TODO: the '=' thing here relates to the order of
+ # columns as they are placed in the "columns"
+ # collection of a CompositeSelect, illustrated in
+ # test/sql/selectable.SelectableTest.testunion make
+ # this relationship less brittle
if cx is None or cp._distance <= cx._distance:
self._orig_cols[ci] = cp
if self.oid_column is not None:
for ci in self.oid_column.orig_set:
self._orig_cols[ci] = self.oid_column
-
+
def _flatten_exportable_columns(self):
- """return the list of ColumnElements represented within this FromClause's _exportable_columns"""
+ """Return the list of ColumnElements represented within this FromClause's _exportable_columns"""
export = self._exportable_columns()
for column in export:
if isinstance(column, Selectable):
@@ -1871,7 +1873,7 @@ class FromClause(Selectable):
yield column
else:
continue
-
+
def _exportable_columns(self):
return []
@@ -1885,7 +1887,7 @@ class _BindParamClause(ClauseElement, _CompareMixin):
"""
__visit_name__ = 'bindparam'
-
+
def __init__(self, key, value, shortname=None, type_=None, unique=False, isoutparam=False):
"""Construct a _BindParamClause.
@@ -1915,11 +1917,11 @@ class _BindParamClause(ClauseElement, _CompareMixin):
execution time.
unique
- if True, the key name of this BindParamClause will be
- modified if another ``_BindParamClause`` of the same
- name already has been located within the containing
+ if True, the key name of this BindParamClause will be
+ modified if another ``_BindParamClause`` of the same name
+ already has been located within the containing
``ClauseElement``.
-
+
isoutparam
if True, the parameter should be treated like a stored procedure "OUT"
parameter.
@@ -1935,7 +1937,7 @@ class _BindParamClause(ClauseElement, _CompareMixin):
self.type = sqltypes.to_instance(_BindParamClause.type_map[type(value)])
else:
self.type = type_
-
+
# TODO: move to types module, obviously
type_map = {
str : sqltypes.String,
@@ -1943,7 +1945,7 @@ class _BindParamClause(ClauseElement, _CompareMixin):
int : sqltypes.Integer,
float : sqltypes.Numeric
}
-
+
def _get_from_objects(self, **modifiers):
return []
@@ -1976,7 +1978,7 @@ class _TypeClause(ClauseElement):
"""
__visit_name__ = 'typeclause'
-
+
def __init__(self, type):
self.type = type
@@ -1990,7 +1992,7 @@ class _TextClause(ClauseElement):
"""
__visit_name__ = 'textclause'
-
+
def __init__(self, text = "", bind=None, bindparams=None, typemap=None):
self._bind = bind
self.bindparams = {}
@@ -2002,7 +2004,7 @@ class _TextClause(ClauseElement):
def repl(m):
self.bindparams[m.group(1)] = bindparam(m.group(1))
return ":%s" % m.group(1)
-
+
# scan the string and search for bind parameter names, add them
# to the list of bindparams
self.text = BIND_PARAMS.sub(repl, text)
@@ -2052,7 +2054,7 @@ class ClauseList(ClauseElement):
By default, is comma-separated, such as a column listing.
"""
__visit_name__ = 'clauselist'
-
+
def __init__(self, *clauses, **kwargs):
self.clauses = []
self.operator = kwargs.pop('operator', operators.comma_op)
@@ -2067,10 +2069,12 @@ class ClauseList(ClauseElement):
return iter(self.clauses)
def __len__(self):
return len(self.clauses)
-
+
def append(self, clause):
- # TODO: not sure if i like the 'group_contents' flag. need to define the difference between
- # a ClauseList of ClauseLists, and a "flattened" ClauseList of ClauseLists. flatten() method ?
+ # TODO: not sure if i like the 'group_contents' flag. need to
+ # define the difference between a ClauseList of ClauseLists,
+ # and a "flattened" ClauseList of ClauseLists. flatten()
+ # method ?
if self.group_contents:
self.clauses.append(_literal_as_text(clause).self_group(against=self.operator))
else:
@@ -2116,8 +2120,9 @@ class _CalculatedClause(ColumnElement):
Extends ``ColumnElement`` to provide column-level comparison
operators.
"""
+
__visit_name__ = 'calculatedclause'
-
+
def __init__(self, name, *clauses, **kwargs):
self.name = name
self.type = sqltypes.to_instance(kwargs.get('type_', None))
@@ -2128,22 +2133,22 @@ class _CalculatedClause(ColumnElement):
self.clause_expr = clauses.self_group()
else:
self.clause_expr = clauses
-
+
key = property(lambda self:self.name or "_calc_")
def _copy_internals(self):
self.clause_expr = self.clause_expr._clone()
-
+
def clauses(self):
if isinstance(self.clause_expr, _Grouping):
return self.clause_expr.elem
else:
return self.clause_expr
clauses = property(clauses)
-
+
def get_children(self, **kwargs):
return self.clause_expr,
-
+
def _get_from_objects(self, **modifiers):
return self.clauses._get_from_objects(**modifiers)
@@ -2178,17 +2183,18 @@ class _Function(_CalculatedClause, FromClause):
key = property(lambda self:self.name)
columns = property(lambda self:[self])
-
+
def _copy_internals(self):
_CalculatedClause._copy_internals(self)
self._clone_from_clause()
def get_children(self, **kwargs):
return _CalculatedClause.get_children(self, **kwargs)
-
+
def append(self, clause):
self.clauses.append(_literal_as_binds(clause, self.name))
+
class _Cast(ColumnElement):
def __init__(self, clause, totype, **kwargs):
@@ -2198,7 +2204,7 @@ class _Cast(ColumnElement):
self.clause = clause
self.typeclause = _TypeClause(self.type)
self._distance = 0
-
+
def _copy_internals(self):
self.clause = self.clause._clone()
self.typeclause = self.typeclause._clone()
@@ -2224,11 +2230,11 @@ class _UnaryExpression(ColumnElement):
def __init__(self, element, operator=None, modifier=None, type_=None, negate=None):
self.operator = operator
self.modifier = modifier
-
+
self.element = _literal_as_text(element).self_group(against=self.operator or self.modifier)
self.type = sqltypes.to_instance(type_)
self.negate = negate
-
+
def _get_from_objects(self, **modifiers):
return self.element._get_from_objects(**modifiers)
@@ -2242,7 +2248,8 @@ class _UnaryExpression(ColumnElement):
"""Compare this ``_UnaryExpression`` against the given ``ClauseElement``."""
return (
- isinstance(other, _UnaryExpression) and self.operator == other.operator and
+ isinstance(other, _UnaryExpression) and
+ self.operator == other.operator and
self.modifier == other.modifier and
self.element.compare(other.element)
)
@@ -2252,7 +2259,7 @@ class _UnaryExpression(ColumnElement):
return _UnaryExpression(self.element, operator=self.negate, negate=self.operator, modifier=self.modifier, type_=self.type)
else:
return super(_UnaryExpression, self)._negate()
-
+
def self_group(self, against):
if self.operator and PRECEDENCE.get(self.operator, PRECEDENCE[_smallest]) <= PRECEDENCE.get(against, PRECEDENCE[_largest]):
return _Grouping(self)
@@ -2262,7 +2269,7 @@ class _UnaryExpression(ColumnElement):
class _BinaryExpression(ColumnElement):
"""Represent an expression that is ``LEFT <operator> RIGHT``."""
-
+
def __init__(self, left, right, operator, type_=None, negate=None):
self.left = _literal_as_text(left).self_group(against=operator)
self.right = _literal_as_text(right).self_group(against=operator)
@@ -2284,23 +2291,28 @@ class _BinaryExpression(ColumnElement):
"""Compare this ``_BinaryExpression`` against the given ``_BinaryExpression``."""
return (
- isinstance(other, _BinaryExpression) and self.operator == other.operator and
+ isinstance(other, _BinaryExpression) and
+ self.operator == other.operator and
+ (
+ self.left.compare(other.left) and
+ self.right.compare(other.right) or
(
- self.left.compare(other.left) and self.right.compare(other.right)
- or (
- self.operator in [operators.eq, operators.ne, operators.add, operators.mul] and
- self.left.compare(other.right) and self.right.compare(other.left)
- )
+ self.operator in [operators.eq, operators.ne,
+ operators.add, operators.mul] and
+ self.left.compare(other.right) and
+ self.right.compare(other.left)
)
+ )
)
-
+
def self_group(self, against=None):
- # use small/large defaults for comparison so that unknown operators are always parenthesized
+ # use small/large defaults for comparison so that unknown
+ # operators are always parenthesized
if self.operator != against and (PRECEDENCE.get(self.operator, PRECEDENCE[_smallest]) <= PRECEDENCE.get(against, PRECEDENCE[_largest])):
return _Grouping(self)
else:
return self
-
+
def _negate(self):
if self.negate is not None:
return _BinaryExpression(self.left, self.right, self.negate, negate=self.operator, type_=self.type)
@@ -2309,7 +2321,7 @@ class _BinaryExpression(ColumnElement):
class _Exists(_UnaryExpression):
__visit_name__ = _UnaryExpression.__visit_name__
-
+
def __init__(self, *args, **kwargs):
kwargs['correlate'] = True
s = select(*args, **kwargs).as_scalar().self_group()
@@ -2322,24 +2334,23 @@ class _Exists(_UnaryExpression):
e = self._clone()
e.element = self.element.correlate(fromclause).self_group()
return e
-
+
def where(self, clause):
e = self._clone()
e.element = self.element.where(clause).self_group()
return e
-
+
def _hide_froms(self, **modifiers):
return self._get_from_objects(**modifiers)
class Join(FromClause):
- """represent a ``JOIN`` construct between two ``FromClause``
- elements.
-
- the public constructor function for ``Join`` is the module-level
+ """represent a ``JOIN`` construct between two ``FromClause`` elements.
+
+ The public constructor function for ``Join`` is the module-level
``join()`` function, as well as the ``join()`` method available
off all ``FromClause`` subclasses.
-
"""
+
def __init__(self, left, right, onclause=None, isouter = False):
self.left = _selectable(left)
self.right = _selectable(right).self_group()
@@ -2350,13 +2361,13 @@ class Join(FromClause):
self.isouter = isouter
self.__folded_equivalents = None
self._init_primary_key()
-
+
name = property(lambda s: "Join object on " + s.left.name + " " + s.right.name)
encodedname = property(lambda s: s.name.encode('ascii', 'backslashreplace'))
def _init_primary_key(self):
pkcol = util.Set([c for c in self._flatten_exportable_columns() if c.primary_key])
-
+
equivs = {}
def add_equiv(a, b):
for x, y in ((a, b), (b, a)):
@@ -2364,18 +2375,18 @@ class Join(FromClause):
equivs[x].add(y)
else:
equivs[x] = util.Set([y])
-
+
class BinaryVisitor(ClauseVisitor):
def visit_binary(self, binary):
if binary.operator == operators.eq:
add_equiv(binary.left, binary.right)
BinaryVisitor().traverse(self.onclause)
-
+
for col in pkcol:
for fk in col.foreign_keys:
if fk.column in pkcol:
add_equiv(col, fk.column)
-
+
omit = util.Set()
for col in pkcol:
p = col
@@ -2383,14 +2394,14 @@ class Join(FromClause):
if p.references(c) or (c.primary_key and not p.primary_key):
omit.add(p)
p = c
-
+
self.__primary_key = ColumnSet([c for c in self._flatten_exportable_columns() if c.primary_key and c not in omit])
primary_key = property(lambda s:s.__primary_key)
def self_group(self, against=None):
return _FromGrouping(self)
-
+
def _locate_oid_column(self):
return self.left.oid_column
@@ -2429,14 +2440,16 @@ class Join(FromClause):
constraints.add(fk.constraint)
self.foreignkey = fk.parent
if len(crit) == 0:
- raise exceptions.ArgumentError("Can't find any foreign key relationships "
- "between '%s' and '%s'" % (primary.name, secondary.name))
+ raise exceptions.ArgumentError(
+ "Can't find any foreign key relationships "
+ "between '%s' and '%s'" % (primary.name, secondary.name))
elif len(constraints) > 1:
- raise exceptions.ArgumentError("Can't determine join between '%s' and '%s'; "
- "tables have more than one foreign key "
- "constraint relationship between them. "
- "Please specify the 'onclause' of this "
- "join explicitly." % (primary.name, secondary.name))
+ raise exceptions.ArgumentError(
+ "Can't determine join between '%s' and '%s'; "
+ "tables have more than one foreign key "
+ "constraint relationship between them. "
+ "Please specify the 'onclause' of this "
+ "join explicitly." % (primary.name, secondary.name))
elif len(crit) == 1:
return (crit[0])
else:
@@ -2475,31 +2488,33 @@ class Join(FromClause):
folded_equivalents = property(_get_folded_equivalents, doc="Returns the column list of this Join with all equivalently-named, "
"equated columns folded into one column, where 'equated' means they are "
- "equated to each other in the ON clause of this join.")
-
+ "equated to each other in the ON clause of this join.")
+
def select(self, whereclause = None, fold_equivalents=False, **kwargs):
"""Create a ``Select`` from this ``Join``.
-
+
whereclause
- the WHERE criterion that will be sent to the ``select()`` function
-
+ the WHERE criterion that will be sent to the ``select()``
+ function
+
fold_equivalents
- based on the join criterion of this ``Join``, do not include repeat
- column names in the column list of the resulting select, for columns that
- are calculated to be "equivalent" based on the join criterion of this
- ``Join``. this will recursively apply to any joins directly nested by
- this one as well.
-
+ based on the join criterion of this ``Join``, do not include
+ repeat column names in the column list of the resulting
+ select, for columns that are calculated to be "equivalent"
+ based on the join criterion of this ``Join``. This will
+ recursively apply to any joins directly nested by this one
+ as well.
+
\**kwargs
all other kwargs are sent to the underlying ``select()`` function.
See the ``select()`` module level function for details.
-
"""
+
if fold_equivalents:
collist = self.folded_equivalents
else:
collist = [self.left, self.right]
-
+
return select(collist, whereclause, from_obj=[self], **kwargs)
bind = property(lambda s:s.left.bind or s.right.bind)
@@ -2519,16 +2534,17 @@ class Join(FromClause):
return [self] + self.onclause._get_from_objects(**modifiers) + self.left._get_from_objects(**modifiers) + self.right._get_from_objects(**modifiers)
class Alias(FromClause):
- """represent an alias, as typically applied to any
- table or sub-select within a SQL statement using the
- ``AS`` keyword (or without the keyword on certain databases
- such as Oracle).
-
- this object is constructed from the ``alias()`` module level function
- as well as the ``alias()`` method available on all ``FromClause``
- subclasses.
-
+ """Represents an table or selectable alias (AS).
+
+ Represents an alias, as typically applied to any table or
+ sub-select within a SQL statement using the ``AS`` keyword (or
+ without the keyword on certain databases such as Oracle).
+
+ This object is constructed from the ``alias()`` module level
+ function as well as the ``alias()`` method available on all
+ ``FromClause`` subclasses.
"""
+
def __init__(self, selectable, alias=None):
baseselectable = selectable
while isinstance(baseselectable, Alias):
@@ -2541,7 +2557,7 @@ class Alias(FromClause):
alias = '{ANON %d %s}' % (id(self), alias or 'anon')
self.name = alias
self.encodedname = alias.encode('ascii', 'backslashreplace')
-
+
def is_derived_from(self, fromclause):
x = self.selectable
while True:
@@ -2584,23 +2600,23 @@ class Alias(FromClause):
for c in self.c:
yield c
yield self.selectable
-
+
def _get_from_objects(self):
return [self]
bind = property(lambda s: s.selectable.bind)
class _ColumnElementAdapter(ColumnElement):
- """adapts a ClauseElement which may or may not be a
+ """Adapts a ClauseElement which may or may not be a
ColumnElement subclass itself into an object which
acts like a ColumnElement.
"""
-
+
def __init__(self, elem):
self.elem = elem
self.type = getattr(elem, 'type', None)
self.orig_set = getattr(elem, 'orig_set', util.Set())
-
+
key = property(lambda s: s.elem.key)
_label = property(lambda s: s.elem._label)
@@ -2620,11 +2636,11 @@ class _ColumnElementAdapter(ColumnElement):
return getattr(self.elem, attr)
class _Grouping(_ColumnElementAdapter):
- """represent a grouping within a column expression"""
+ """Represent a grouping within a column expression"""
pass
class _FromGrouping(FromClause):
- """represent a grouping of a FROM clause"""
+ """Represent a grouping of a FROM clause"""
__visit_name__ = 'grouping'
def __init__(self, elem):
@@ -2646,17 +2662,18 @@ class _FromGrouping(FromClause):
def __getattr__(self, attr):
return getattr(self.elem, attr)
-
+
class _Label(ColumnElement):
- """represent a label, as typically applied to any column-level element
- using the ``AS`` sql keyword.
-
- this object is constructed from the ``label()`` module level function
- as well as the ``label()`` method available on all ``ColumnElement``
- subclasses.
-
+ """Represents a column label (AS).
+
+ Represent a label, as typically applied to any column-level
+ element using the ``AS`` sql keyword.
+
+ This object is constructed from the ``label()`` module level
+ function as well as the ``label()`` method available on all
+ ``ColumnElement`` subclasses.
"""
-
+
def __init__(self, name, obj, type_=None):
while isinstance(obj, _Label):
obj = obj.obj
@@ -2671,7 +2688,7 @@ class _Label(ColumnElement):
def expression_element(self):
return self.obj
-
+
def _copy_internals(self):
self.obj = self.obj._clone()
@@ -2683,7 +2700,7 @@ class _Label(ColumnElement):
def _hide_froms(self, **modifiers):
return self.obj._hide_froms(**modifiers)
-
+
def _make_proxy(self, selectable, name = None):
if isinstance(self.obj, (Selectable, ColumnElement)):
return self.obj._make_proxy(selectable, name=self.name)
@@ -2692,28 +2709,29 @@ class _Label(ColumnElement):
class _ColumnClause(ColumnElement):
"""Represents a generic column expression from any textual string.
+
This includes columns associated with tables, aliases and select
- statements, but also any arbitrary text. May or may not be bound
+ statements, but also any arbitrary text. May or may not be bound
to an underlying ``Selectable``. ``_ColumnClause`` is usually
- created publically via the ``column()`` function or the
+ created publically via the ``column()`` function or the
``literal_column()`` function.
-
- text
- the text of the element.
-
- selectable
- parent selectable.
-
- type
- ``TypeEngine`` object which can associate this ``_ColumnClause``
- with a type.
-
- is_literal
- if True, the ``_ColumnClause`` is assumed to be an exact expression
- that will be delivered to the output with no quoting rules applied
- regardless of case sensitive settings. the ``literal_column()`` function is
- usually used to create such a ``_ColumnClause``.
-
+
+ text
+ the text of the element.
+
+ selectable
+ parent selectable.
+
+ type
+ ``TypeEngine`` object which can associate this ``_ColumnClause``
+ with a type.
+
+ is_literal
+ if True, the ``_ColumnClause`` is assumed to be an exact
+ expression that will be delivered to the output with no quoting
+ rules applied regardless of case sensitive settings. the
+ ``literal_column()`` function is usually used to create such a
+ ``_ColumnClause``.
"""
def __init__(self, text, selectable=None, type_=None, _is_oid=False, is_literal=False):
@@ -2725,20 +2743,20 @@ class _ColumnClause(ColumnElement):
self._distance = 0
self.__label = None
self.is_literal = is_literal
-
+
def _clone(self):
# ColumnClause is immutable
return self
-
+
def _get_label(self):
"""Generate a 'label' for this column.
-
+
The label is a product of the parent table name and column
name, and is treated as a unique identifier of this ``Column``
across all ``Tables`` and derived selectables for a particular
metadata collection.
"""
-
+
# for a "literal" column, we've no idea what the text is
# therefore no 'label' can be automatically generated
if self.is_literal:
@@ -2765,7 +2783,7 @@ class _ColumnClause(ColumnElement):
return self
else:
return super(_ColumnClause, self).label(name)
-
+
def _get_from_objects(self, **modifiers):
if self.table is not None:
return [self.table]
@@ -2790,21 +2808,20 @@ class _ColumnClause(ColumnElement):
return self.type
class TableClause(FromClause):
- """represents a "table" construct.
-
- Note that this represents tables only as another
- syntactical construct within SQL expressions; it
- does not provide schema-level functionality.
-
+ """Represents a "table" construct.
+
+ Note that this represents tables only as another syntactical
+ construct within SQL expressions; it does not provide schema-level
+ functionality.
"""
-
+
def __init__(self, name, *columns):
super(TableClause, self).__init__(name)
self.name = self.fullname = name
self.encodedname = self.name.encode('ascii', 'backslashreplace')
self._oid_column = _ColumnClause('oid', self, _is_oid=True)
self._export_columns(columns)
-
+
def _clone(self):
# TableClause is immutable
return self
@@ -2875,7 +2892,7 @@ class TableClause(FromClause):
def _get_from_objects(self, **modifiers):
return [self]
-
+
class _SelectBaseMixin(object):
"""Base class for ``Select`` and ``CompoundSelects``."""
@@ -2885,21 +2902,21 @@ class _SelectBaseMixin(object):
self._limit = limit
self._offset = offset
self._bind = bind
-
+
self.append_order_by(*util.to_list(order_by, []))
self.append_group_by(*util.to_list(group_by, []))
-
+
def as_scalar(self):
return _ScalarSelect(self)
-
+
def apply_labels(self):
s = self._generate()
s.use_labels = True
return s
-
+
def label(self, name):
return self.as_scalar().label(name)
-
+
def supports_execution(self):
return True
@@ -2907,17 +2924,17 @@ class _SelectBaseMixin(object):
s = self._clone()
s._clone_from_clause()
return s
-
+
def limit(self, limit):
s = self._generate()
s._limit = limit
return s
-
+
def offset(self, offset):
s = self._generate()
s._offset = offset
return s
-
+
def order_by(self, *clauses):
s = self._generate()
s.append_order_by(*clauses)
@@ -2943,7 +2960,7 @@ class _SelectBaseMixin(object):
if getattr(self, '_group_by_clause', None):
clauses = list(self._group_by_clause) + list(clauses)
self._group_by_clause = ClauseList(*clauses)
-
+
def select(self, whereclauses = None, **params):
return select([self], whereclauses, **params)
@@ -2964,7 +2981,7 @@ class _ScalarSelect(_Grouping):
raise exceptions.InvalidRequestError("Scalar Select expression has no columns; use this object directly within a column-level expression.")
c = property(_no_cols)
columns = c
-
+
def self_group(self, **kwargs):
return self
@@ -3037,7 +3054,7 @@ class CompoundSelect(_SelectBaseMixin, FromClause):
for s in self.selects:
for t in s._table_iterator():
yield t
-
+
def _find_engine(self):
for s in self.selects:
e = s._find_engine()
@@ -3047,18 +3064,20 @@ class CompoundSelect(_SelectBaseMixin, FromClause):
return None
class Select(_SelectBaseMixin, FromClause):
- """Represent a ``SELECT`` statement, with appendable clauses, as
- well as the ability to execute itself and return a result set.
-
+ """Represents a ``SELECT`` statement.
+
+ Select statements support appendable clauses, as well as the
+ ability to execute themselves and return a result set.
"""
def __init__(self, columns, whereclause=None, from_obj=None, distinct=False, having=None, correlate=True, prefixes=None, **kwargs):
- """construct a Select object.
-
- The public constructor for Select is the [sqlalchemy.sql#select()] function;
- see that function for argument descriptions.
+ """Construct a Select object.
+
+ The public constructor for Select is the
+ [sqlalchemy.sql#select()] function; see that function for
+ argument descriptions.
"""
-
+
self._should_correlate = correlate
self._distinct = distinct
@@ -3068,7 +3087,7 @@ class Select(_SelectBaseMixin, FromClause):
self._whereclause = None
self._having = None
self._prefixes = []
-
+
if columns is not None:
for c in columns:
self.append_column(c)
@@ -3079,24 +3098,28 @@ class Select(_SelectBaseMixin, FromClause):
if whereclause is not None:
self.append_whereclause(whereclause)
-
+
if having is not None:
self.append_having(having)
+ if prefixes is not None:
+ for p in prefixes:
+ self.append_prefix(p)
+
_SelectBaseMixin.__init__(self, **kwargs)
def _get_display_froms(self, existing_froms=None):
- """return the full list of 'from' clauses to be displayed.
-
- takes into account a set of existing froms which
- may be rendered in the FROM clause of enclosing selects;
- this Select may want to leave those absent if it is automatically
+ """Return the full list of 'from' clauses to be displayed.
+
+ Takes into account a set of existing froms which may be
+ rendered in the FROM clause of enclosing selects; this Select
+ may want to leave those absent if it is automatically
correlating.
"""
froms = util.OrderedSet()
hide_froms = util.Set()
-
+
for col in self._raw_columns:
for f in col._hide_froms():
hide_froms.add(f)
@@ -3106,7 +3129,7 @@ class Select(_SelectBaseMixin, FromClause):
if self._whereclause is not None:
for f in self._whereclause._get_from_objects(is_where=True):
froms.add(f)
-
+
for elem in self._froms:
froms.add(elem)
for f in elem._get_from_objects():
@@ -3117,7 +3140,7 @@ class Select(_SelectBaseMixin, FromClause):
hide_froms.add(f)
froms = froms.difference(hide_froms)
-
+
if len(froms) > 1:
corr = self.__correlate
if self._should_correlate and existing_froms is not None:
@@ -3128,7 +3151,7 @@ class Select(_SelectBaseMixin, FromClause):
return f
else:
return froms
-
+
froms = property(_get_display_froms, doc="""Return a list of all FromClause elements which will be applied to the FROM clause of the resulting statement.""")
name = property(lambda self:"Select statement")
@@ -3142,7 +3165,7 @@ class Select(_SelectBaseMixin, FromClause):
if self._whereclause is not None:
for f in self._whereclause._get_from_objects(is_where=True):
froms.add(f)
-
+
for elem in self._froms:
froms.add(elem)
for f in elem._get_from_objects():
@@ -3156,9 +3179,9 @@ class Select(_SelectBaseMixin, FromClause):
yield co
else:
yield c
-
+
inner_columns = property(_get_inner_columns)
-
+
def _copy_internals(self):
self._clone_from_clause()
self._raw_columns = [c._clone() for c in self._raw_columns]
@@ -3185,22 +3208,22 @@ class Select(_SelectBaseMixin, FromClause):
oldfroms.remove(old)
self.__correlate = self.__correlate.union(newcorrelate)
self._froms = [f for f in oldfroms.union(newfroms)]
-
+
def column(self, column):
s = self._generate()
s.append_column(column)
return s
-
+
def where(self, whereclause):
s = self._generate()
s.append_whereclause(whereclause)
return s
-
+
def having(self, having):
s = self._generate()
s.append_having(having)
return s
-
+
def distinct(self):
s = self._generate()
s._distinct = True
@@ -3210,17 +3233,17 @@ class Select(_SelectBaseMixin, FromClause):
s = self._generate()
s.append_prefix(clause)
return s
-
+
def select_from(self, fromclause):
s = self._generate()
s.append_from(fromclause)
return s
-
+
def __dont_correlate(self):
s = self._generate()
s._should_correlate = False
return s
-
+
def correlate(self, fromclause):
s = self._generate()
s._should_correlate=False
@@ -3229,10 +3252,10 @@ class Select(_SelectBaseMixin, FromClause):
else:
s.append_correlation(fromclause)
return s
-
+
def append_correlation(self, fromclause):
self.__correlate.add(fromclause)
-
+
def append_column(self, column):
column = _literal_as_column(column)
@@ -3240,17 +3263,17 @@ class Select(_SelectBaseMixin, FromClause):
column = column.self_group(against=operators.comma_op)
self._raw_columns.append(column)
-
+
def append_prefix(self, clause):
clause = _literal_as_text(clause)
self._prefixes.append(clause)
-
+
def append_whereclause(self, whereclause):
if self._whereclause is not None:
self._whereclause = and_(self._whereclause, _literal_as_text(whereclause))
else:
self._whereclause = _literal_as_text(whereclause)
-
+
def append_having(self, having):
if self._having is not None:
self._having = and_(self._having, _literal_as_text(having))
@@ -3264,7 +3287,7 @@ class Select(_SelectBaseMixin, FromClause):
def _exportable_columns(self):
return [c for c in self._raw_columns if isinstance(c, (Selectable, ColumnElement))]
-
+
def _proxy_column(self, column):
if self.use_labels:
return column._make_proxy(self, name=column._label)
@@ -3279,8 +3302,9 @@ class Select(_SelectBaseMixin, FromClause):
def _locate_oid_column(self):
for f in self.locate_all_froms():
if f is self:
- # we might be in our own _froms list if a column with us as the parent is attached,
- # which includes textual columns.
+ # we might be in our own _froms list if a column with
+ # us as the parent is attached, which includes textual
+ # columns.
continue
oid = f.oid_column
if oid is not None:
@@ -3310,7 +3334,7 @@ class Select(_SelectBaseMixin, FromClause):
for t in NoColumnVisitor().iterate(self):
if isinstance(t, TableClause):
yield t
-
+
def _find_engine(self):
"""Try to return a Engine, either explicitly set in this
object, or searched within the from clauses for one.
@@ -3344,11 +3368,9 @@ class _UpdateBase(ClauseElement):
def _table_iterator(self):
return iter([self.table])
-
+
def _process_colparams(self, parameters):
- """Receive the *values* of an ``INSERT`` or ``UPDATE``
- statement and construct appropriate bind parameters.
- """
+ """Receive the *values* of an ``INSERT`` or ``UPDATE`` statement and construct appropriate bind parameters."""
if parameters is None:
return None
@@ -3404,7 +3426,7 @@ class Insert(_UpdateBase):
u.parameters = self.parameters.copy()
u.parameters.update(u._process_colparams(v))
return u
-
+
class Update(_UpdateBase):
def __init__(self, table, whereclause, values=None):
self.table = table
@@ -3420,7 +3442,7 @@ class Update(_UpdateBase):
def _copy_internals(self):
self._whereclause = self._whereclause._clone()
self.parameters = self.parameters.copy()
-
+
def values(self, v):
if len(v) == 0:
return self