diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-02-10 14:17:08 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-02-10 14:17:08 -0500 |
commit | 3f9a343d725eea883aba2145de4cbb7b84f9d08c (patch) | |
tree | f55e890195c76543e689c3b939b84df15cd80a3e /lib/sqlalchemy/sql/expression.py | |
parent | a6d54d18c1ddac30940affaa940edaad59e5d63f (diff) | |
download | sqlalchemy-3f9a343d725eea883aba2145de4cbb7b84f9d08c.tar.gz |
- Query.distinct() now accepts column expressions
as *args, interpreted by the Postgresql dialect
as DISTINCT ON (<expr>). [ticket:1069]
- select.distinct() now accepts column expressions
as *args, interpreted by the Postgresql dialect
as DISTINCT ON (<expr>). Note this was already
available via passing a list to the `distinct`
keyword argument to select(). [ticket:1069]
- select.prefix_with() accepts multiple expressions
(i.e. *expr), 'prefix' keyword argument to select()
accepts a list or tuple.
- Passing a string to the `distinct` keyword argument
of `select()` for the purpose of emitting special
MySQL keywords (DISTINCTROW etc.) is deprecated -
use `prefix_with()` for this.
- put kw arguments to select() in order
- restore docs for _SelectBase, renamed from _SelectBaseMixin
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 141 |
1 files changed, 100 insertions, 41 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 04ca147bb..4287216a4 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -187,23 +187,38 @@ def select(columns=None, whereclause=None, from_obj=[], **kwargs): Deprecated. Use .execution_options(autocommit=<True|False>) to set the autocommit option. - :param prefixes: - a list of strings or :class:`ClauseElement` objects to include - directly after the SELECT keyword in the generated statement, - for dialect-specific query features. + :param bind=None: + an :class:`~.base.Engine` or :class:`~.base.Connection` instance + to which the + resulting :class:`.Select` object will be bound. The :class:`.Select` + object will otherwise automatically bind to whatever + :class:`~.base.Connectable` instances can be located within its contained + :class:`.ClauseElement` members. + + :param correlate=True: + indicates that this :class:`Select` object should have its + contained :class:`FromClause` elements "correlated" to an enclosing + :class:`Select` object. This means that any :class:`ClauseElement` + instance within the "froms" collection of this :class:`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. :param distinct=False: when ``True``, applies a ``DISTINCT`` qualifier to the columns clause of the resulting statement. - - :param 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 :class:`Select` object will use these - names as well for targeting column members. + + The boolean argument may also be a column expression or list + of column expressions - this is a special calling form which + is understood by the Postgresql dialect to render the + ``DISTINCT ON (<columns>)`` syntax. + + ``distinct`` is also available via the :meth:`~.Select.distinct` + generative method. + + .. note:: The ``distinct`` keyword's acceptance of a string + argument for usage with MySQL is deprecated. Use + the ``prefixes`` argument or :meth:`~.Select.prefix_with`. :param for_update=False: when ``True``, applies ``FOR UPDATE`` to the end of the @@ -213,15 +228,6 @@ def select(columns=None, whereclause=None, from_obj=[], **kwargs): and oracle supports "nowait" which translates to ``FOR UPDATE NOWAIT``. - :param correlate=True: - indicates that this :class:`Select` object should have its - contained :class:`FromClause` elements "correlated" to an enclosing - :class:`Select` object. This means that any :class:`ClauseElement` - instance within the "froms" collection of this :class:`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. - :param group_by: a list of :class:`ClauseElement` objects which will comprise the ``GROUP BY`` clause of the resulting select. @@ -230,10 +236,6 @@ def select(columns=None, whereclause=None, from_obj=[], **kwargs): a :class:`ClauseElement` that will comprise the ``HAVING`` clause of the resulting select when ``GROUP BY`` is used. - :param order_by: - a scalar or list of :class:`ClauseElement` objects which will - comprise the ``ORDER BY`` clause of the resulting select. - :param limit=None: a numerical value which usually compiles to a ``LIMIT`` expression in the resulting select. Databases that don't @@ -246,13 +248,29 @@ def select(columns=None, whereclause=None, from_obj=[], **kwargs): support ``OFFSET`` will attempt to provide similar functionality. - :param 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 - :class:`ClauseElement` members. + :param order_by: + a scalar or list of :class:`ClauseElement` objects which will + comprise the ``ORDER BY`` clause of the resulting select. + :param prefixes: + a list of strings or :class:`ClauseElement` objects to include + directly after the SELECT keyword in the generated statement, + for dialect-specific query features. ``prefixes`` is + also available via the :meth:`~.Select.prefix_with` + generative method. + + :param 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 :class:`Select` object will use these + names as well for targeting column members. + + use_labels is also available via the :meth:`~._SelectBase.apply_labels` + generative method. + """ return Select(columns, whereclause=whereclause, from_obj=from_obj, **kwargs) @@ -4085,6 +4103,7 @@ class Select(_SelectBase): _prefixes = () _hints = util.immutabledict() + _distinct = False def __init__(self, columns, @@ -4106,7 +4125,24 @@ class Select(_SelectBase): """ self._should_correlate = correlate - self._distinct = distinct + if distinct is not False: + if isinstance(distinct, basestring): + util.warn_deprecated( + "A string argument passed to the 'distinct' " + "keyword argument of 'select()' is deprecated " + "- please use 'prefixes' or 'prefix_with()' " + "to specify additional prefixes") + if prefixes: + prefixes = util.to_list(prefixes) + [distinct] + else: + prefixes = [distinct] + elif distinct is True: + self._distinct = True + else: + self._distinct = [ + _literal_as_text(e) + for e in util.to_list(distinct) + ] self._correlate = set() self._froms = util.OrderedSet() @@ -4329,21 +4365,44 @@ class Select(_SelectBase): self.append_having(having) @_generative - def distinct(self): - """return a new select() construct which will apply DISTINCT to its + def distinct(self, *expr): + """Return a new select() construct which will apply DISTINCT to its columns clause. - """ - self._distinct = True + :param \*expr: optional column expressions. When present, + the Postgresql dialect will render a ``DISTINCT ON (<expressions>>)`` + construct. + + """ + if expr: + expr = [_literal_as_text(e) for e in expr] + if isinstance(self._distinct, list): + self._distinct = self._distinct + expr + else: + self._distinct = expr + else: + self._distinct = True @_generative - def prefix_with(self, clause): + def prefix_with(self, *expr): """return a new select() construct which will apply the given - expression to the start of its columns clause, not using any commas. + expressions, typically strings, to the start of its columns clause, + not using any commas. In particular is useful for MySQL + keywords. + + e.g.:: + + select(['a', 'b']).prefix_with('HIGH_PRIORITY', + 'SQL_SMALL_RESULT', + 'ALL') + + Would render:: + + SELECT HIGH_PRIORITY SQL_SMALL_RESULT ALL a, b """ - clause = _literal_as_text(clause) - self._prefixes = self._prefixes + (clause,) + expr = tuple(_literal_as_text(e) for e in expr) + self._prefixes = self._prefixes + expr @_generative def select_from(self, fromclause): |