diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-04-21 17:18:49 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-04-21 17:18:49 -0400 |
| commit | 3aff498e4a96eda06f09f09f98e73e135719b388 (patch) | |
| tree | f1ca2029cfd147478447d3cb98bae587a8ccb3c2 /lib/sqlalchemy/sql/expression.py | |
| parent | 1f6528ed8581ba63721bdc2a0593a5d39b9c27e0 (diff) | |
| parent | fbcdba12f88d88c509fc34eb8aab3f501d1b705b (diff) | |
| download | sqlalchemy-3aff498e4a96eda06f09f09f98e73e135719b388.tar.gz | |
merge into cymysql branch...
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
| -rw-r--r-- | lib/sqlalchemy/sql/expression.py | 185 |
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' |
