summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/expression.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-04-21 17:18:49 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-04-21 17:18:49 -0400
commit3aff498e4a96eda06f09f09f98e73e135719b388 (patch)
treef1ca2029cfd147478447d3cb98bae587a8ccb3c2 /lib/sqlalchemy/sql/expression.py
parent1f6528ed8581ba63721bdc2a0593a5d39b9c27e0 (diff)
parentfbcdba12f88d88c509fc34eb8aab3f501d1b705b (diff)
downloadsqlalchemy-3aff498e4a96eda06f09f09f98e73e135719b388.tar.gz
merge into cymysql branch...
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
-rw-r--r--lib/sqlalchemy/sql/expression.py185
1 files changed, 133 insertions, 52 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 490004e39..28b1c6ddd 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -181,10 +181,10 @@ def select(columns=None, whereclause=None, from_obj=[], **kwargs):
string arguments, which will be converted as appropriate into
either :func:`text()` or :func:`literal_column()` constructs.
- See also:
+ .. seealso::
- :ref:`coretutorial_selecting` - Core Tutorial description of
- :func:`.select`.
+ :ref:`coretutorial_selecting` - Core Tutorial description of
+ :func:`.select`.
:param columns:
A list of :class:`.ClauseElement` objects, typically
@@ -464,7 +464,7 @@ def update(table, whereclause=None, values=None, inline=False, **kwargs):
as_scalar()
)
- See also:
+ .. seealso::
:ref:`inserts_and_updates` - SQL Expression
Language Tutorial
@@ -493,7 +493,7 @@ def delete(table, whereclause=None, **kwargs):
condition of the ``UPDATE`` statement. Note that the
:meth:`~Delete.where()` generative method may be used instead.
- See also:
+ .. seealso::
:ref:`deletes` - SQL Expression Tutorial
@@ -2873,6 +2873,8 @@ class BindParameter(ColumnElement):
__visit_name__ = 'bindparam'
quote = None
+ _is_crud = False
+
def __init__(self, key, value, type_=None, unique=False,
callable_=None,
isoutparam=False, required=False,
@@ -3073,7 +3075,7 @@ class Executable(Generative):
See :meth:`.Connection.execution_options` for a full list of
possible options.
- See also:
+ .. seealso::
:meth:`.Connection.execution_options()`
@@ -3444,15 +3446,15 @@ class Case(ColumnElement):
class FunctionElement(Executable, ColumnElement, FromClause):
"""Base for SQL function-oriented constructs.
- See also:
+ .. seealso::
- :class:`.Function` - named SQL function.
+ :class:`.Function` - named SQL function.
- :data:`.func` - namespace which produces registered or ad-hoc
- :class:`.Function` instances.
+ :data:`.func` - namespace which produces registered or ad-hoc
+ :class:`.Function` instances.
- :class:`.GenericFunction` - allows creation of registered function
- types.
+ :class:`.GenericFunction` - allows creation of registered function
+ types.
"""
@@ -3571,15 +3573,13 @@ class Function(FunctionElement):
See the superclass :class:`.FunctionElement` for a description
of public methods.
- See also:
-
- See also:
+ .. seealso::
- :data:`.func` - namespace which produces registered or ad-hoc
- :class:`.Function` instances.
+ :data:`.func` - namespace which produces registered or ad-hoc
+ :class:`.Function` instances.
- :class:`.GenericFunction` - allows creation of registered function
- types.
+ :class:`.GenericFunction` - allows creation of registered function
+ types.
"""
@@ -4725,7 +4725,9 @@ class SelectBase(Executable, FromClause):
"""return a 'scalar' representation of this selectable, embedded as a
subquery with a label.
- See also :meth:`~.SelectBase.as_scalar`.
+ .. seealso::
+
+ :meth:`~.SelectBase.as_scalar`.
"""
return self.as_scalar().label(name)
@@ -4843,9 +4845,9 @@ class SelectBase(Executable, FromClause):
result = conn.execute(statement).fetchall()
- See also:
+ .. seealso::
- :meth:`.orm.query.Query.cte` - ORM version of :meth:`.SelectBase.cte`.
+ :meth:`.orm.query.Query.cte` - ORM version of :meth:`.SelectBase.cte`.
"""
return CTE(self, name=name, recursive=recursive)
@@ -4914,6 +4916,10 @@ class SelectBase(Executable, FromClause):
The criterion will be appended to any pre-existing ORDER BY criterion.
+ This is an **in-place** mutation method; the
+ :meth:`~.SelectBase.order_by` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
if len(clauses) == 1 and clauses[0] is None:
self._order_by_clause = ClauseList()
@@ -4927,6 +4933,10 @@ class SelectBase(Executable, FromClause):
The criterion will be appended to any pre-existing GROUP BY criterion.
+ This is an **in-place** mutation method; the
+ :meth:`~.SelectBase.group_by` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
if len(clauses) == 1 and clauses[0] is None:
self._group_by_clause = ClauseList()
@@ -4980,7 +4990,7 @@ class CompoundSelect(SelectBase):
INTERSECT_ALL = util.symbol('INTERSECT ALL')
def __init__(self, keyword, *selects, **kwargs):
- self._should_correlate = kwargs.pop('correlate', False)
+ self._auto_correlate = kwargs.pop('correlate', False)
self.keyword = keyword
self.selects = []
@@ -5120,13 +5130,13 @@ class HasPrefixes(object):
class Select(HasPrefixes, SelectBase):
"""Represents a ``SELECT`` statement.
- See also:
+ .. seealso::
- :func:`~.expression.select` - the function which creates
- a :class:`.Select` object.
+ :func:`~.expression.select` - the function which creates
+ a :class:`.Select` object.
- :ref:`coretutorial_selecting` - Core Tutorial description
- of :func:`.select`.
+ :ref:`coretutorial_selecting` - Core Tutorial description
+ of :func:`.select`.
"""
@@ -5159,7 +5169,7 @@ class Select(HasPrefixes, SelectBase):
:class:`SelectBase` superclass.
"""
- self._should_correlate = correlate
+ self._auto_correlate = correlate
if distinct is not False:
if distinct is True:
self._distinct = True
@@ -5232,7 +5242,7 @@ class Select(HasPrefixes, SelectBase):
return froms
- def _get_display_froms(self, existing_froms=None):
+ def _get_display_froms(self, existing_froms=None, asfrom=False):
"""Return the full list of 'from' clauses to be displayed.
Takes into account a set of existing froms which may be
@@ -5258,18 +5268,29 @@ class Select(HasPrefixes, SelectBase):
# using a list to maintain ordering
froms = [f for f in froms if f not in toremove]
- if len(froms) > 1 or self._correlate or self._correlate_except:
+ if not asfrom:
if self._correlate:
- froms = [f for f in froms if f not in
- _cloned_intersection(froms,
- self._correlate)]
+ froms = [
+ f for f in froms if f not in
+ _cloned_intersection(
+ _cloned_intersection(froms, existing_froms or ()),
+ self._correlate
+ )
+ ]
if self._correlate_except:
- froms = [f for f in froms if f in _cloned_intersection(froms,
- self._correlate_except)]
- if self._should_correlate and existing_froms:
- froms = [f for f in froms if f not in
- _cloned_intersection(froms,
- existing_froms)]
+ froms = [
+ f for f in froms if f in
+ _cloned_intersection(
+ froms,
+ self._correlate_except
+ )
+ ]
+
+ if self._auto_correlate and existing_froms and len(froms) > 1:
+ froms = [
+ f for f in froms if f not in
+ _cloned_intersection(froms, existing_froms)
+ ]
if not len(froms):
raise exc.InvalidRequestError("Select statement '%s"
@@ -5642,7 +5663,7 @@ class Select(HasPrefixes, SelectBase):
:ref:`correlated_subqueries`
"""
- self._should_correlate = False
+ self._auto_correlate = False
if fromclauses and fromclauses[0] is None:
self._correlate = ()
else:
@@ -5662,7 +5683,7 @@ class Select(HasPrefixes, SelectBase):
:ref:`correlated_subqueries`
"""
- self._should_correlate = False
+ self._auto_correlate = False
if fromclauses and fromclauses[0] is None:
self._correlate_except = ()
else:
@@ -5671,9 +5692,15 @@ class Select(HasPrefixes, SelectBase):
def append_correlation(self, fromclause):
"""append the given correlation expression to this select()
- construct."""
+ construct.
+
+ This is an **in-place** mutation method; the
+ :meth:`~.Select.correlate` method is preferred, as it provides standard
+ :term:`method chaining`.
- self._should_correlate = False
+ """
+
+ self._auto_correlate = False
self._correlate = set(self._correlate).union(
_interpret_as_from(f) for f in fromclause)
@@ -5681,6 +5708,10 @@ class Select(HasPrefixes, SelectBase):
"""append the given column expression to the columns clause of this
select() construct.
+ This is an **in-place** mutation method; the
+ :meth:`~.Select.column` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
self._reset_exported()
column = _interpret_as_column_or_from(column)
@@ -5694,6 +5725,10 @@ class Select(HasPrefixes, SelectBase):
"""append the given columns clause prefix expression to this select()
construct.
+ This is an **in-place** mutation method; the
+ :meth:`~.Select.prefix_with` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
clause = _literal_as_text(clause)
self._prefixes = self._prefixes + (clause,)
@@ -5704,6 +5739,10 @@ class Select(HasPrefixes, SelectBase):
The expression will be joined to existing WHERE criterion via AND.
+ This is an **in-place** mutation method; the
+ :meth:`~.Select.where` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
self._reset_exported()
whereclause = _literal_as_text(whereclause)
@@ -5719,6 +5758,10 @@ class Select(HasPrefixes, SelectBase):
The expression will be joined to existing HAVING criterion via AND.
+ This is an **in-place** mutation method; the
+ :meth:`~.Select.having` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
if self._having is not None:
self._having = and_(self._having, _literal_as_text(having))
@@ -5729,18 +5772,56 @@ class Select(HasPrefixes, SelectBase):
"""append the given FromClause expression to this select() construct's
FROM clause.
+ This is an **in-place** mutation method; the
+ :meth:`~.Select.select_from` method is preferred, as it provides standard
+ :term:`method chaining`.
+
"""
self._reset_exported()
fromclause = _interpret_as_from(fromclause)
self._from_obj = self._from_obj.union([fromclause])
+
+ @_memoized_property
+ def _columns_plus_names(self):
+ if self.use_labels:
+ names = set()
+ def name_for_col(c):
+ if c._label is None:
+ return (None, c)
+ name = c._label
+ if name in names:
+ name = c.anon_label
+ else:
+ names.add(name)
+ return name, c
+
+ return [
+ name_for_col(c)
+ for c in util.unique_list(_select_iterables(self._raw_columns))
+ ]
+ else:
+ return [
+ (None, c)
+ for c in util.unique_list(_select_iterables(self._raw_columns))
+ ]
+
def _populate_column_collection(self):
- for c in self.inner_columns:
- if hasattr(c, '_make_proxy'):
- c._make_proxy(self,
- name=c._label if self.use_labels else None,
- key=c._key_label if self.use_labels else None,
- name_is_truncatable=True)
+ for name, c in self._columns_plus_names:
+ if not hasattr(c, '_make_proxy'):
+ continue
+ if name is None:
+ key = None
+ elif self.use_labels:
+ key = c._key_label
+ if key is not None and key in self.c:
+ key = c.anon_label
+ else:
+ key = None
+
+ c._make_proxy(self, key=key,
+ name=name,
+ name_is_truncatable=True)
def _refresh_for_new_column(self, column):
for fromclause in self._froms:
@@ -6124,9 +6205,9 @@ class Insert(ValuesBase):
The :class:`.Insert` object is created using the
:func:`~.expression.insert()` function.
- See also:
+ .. seealso::
- :ref:`coretutorial_insert_expressions`
+ :ref:`coretutorial_insert_expressions`
"""
__visit_name__ = 'insert'