]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
improve distinct() docs
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 10 Apr 2024 14:28:28 +0000 (10:28 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 10 Apr 2024 14:28:57 +0000 (10:28 -0400)
differentiate more clearly between distinct() and select().distinct().

Change-Id: Id5eae749393e5898ae501b2462ec4c2c54262e2f
(cherry picked from commit da639af16f77118bc17bbf5cf78fe41dd1818168)

lib/sqlalchemy/sql/_elements_constructors.py
lib/sqlalchemy/sql/selectable.py

index 77cc2a8021d3bf45a3260d408d122def69929fd8..51d8ac3999541c5dae8826777e51a916ff55eca4 100644 (file)
@@ -1090,16 +1090,23 @@ def desc(
 def distinct(expr: _ColumnExpressionArgument[_T]) -> UnaryExpression[_T]:
     """Produce an column-expression-level unary ``DISTINCT`` clause.
 
-    This applies the ``DISTINCT`` keyword to an individual column
-    expression, and is typically contained within an aggregate function,
-    as in::
+    This applies the ``DISTINCT`` keyword to an **individual column
+    expression** (e.g. not the whole statement), and renders **specifically
+    in that column position**; this is used for containment within
+    an aggregate function, as in::
 
         from sqlalchemy import distinct, func
-        stmt = select(func.count(distinct(users_table.c.name)))
+        stmt = select(users_table.c.id, func.count(distinct(users_table.c.name)))
+
+    The above would produce an statement resembling::
 
-    The above would produce an expression resembling::
+        SELECT user.id, count(DISTINCT user.name) FROM user
 
-        SELECT COUNT(DISTINCT name) FROM user
+    .. tip:: The :func:`_sql.distinct` function does **not** apply DISTINCT
+       to the full SELECT statement, instead applying a DISTINCT modifier
+       to **individual column expressions**.  For general ``SELECT DISTINCT``
+       support, use the
+       :meth:`_sql.Select.distinct` method on :class:`_sql.Select`.
 
     The :func:`.distinct` function is also available as a column-level
     method, e.g. :meth:`_expression.ColumnElement.distinct`, as in::
@@ -1122,7 +1129,7 @@ def distinct(expr: _ColumnExpressionArgument[_T]) -> UnaryExpression[_T]:
 
         :data:`.func`
 
-    """
+    """  # noqa: E501
     return UnaryExpression._create_distinct(expr)
 
 
index 65978f6646cc2c4314f4246b674c23c47db88457..0f19810ccbbaf57bccf00dd4f34fc4bab8527b15 100644 (file)
@@ -5972,11 +5972,26 @@ class Select(
     @_generative
     def distinct(self, *expr: _ColumnExpressionArgument[Any]) -> Self:
         r"""Return a new :func:`_expression.select` construct which
-        will apply DISTINCT to its columns clause.
+        will apply DISTINCT to the SELECT statement overall.
+
+        E.g.::
+
+            from sqlalchemy import select
+            stmt = select(users_table.c.id, users_table.c.name).distinct()
+
+        The above would produce an statement resembling::
+
+            SELECT DISTINCT user.id, user.name FROM user
+
+        The method also accepts an ``*expr`` parameter which produces the
+        PostgreSQL dialect-specific ``DISTINCT ON`` expression.  Using this
+        parameter on other backends which don't support this syntax will
+        raise an error.
 
         :param \*expr: optional column expressions.  When present,
-         the PostgreSQL dialect will render a ``DISTINCT ON (<expressions>>)``
-         construct.
+         the PostgreSQL dialect will render a ``DISTINCT ON (<expressions>)``
+         construct.  A deprecation warning and/or :class:`_exc.CompileError`
+         will be raised on other backends.
 
          .. deprecated:: 1.4 Using \*expr in other dialects is deprecated
             and will raise :class:`_exc.CompileError` in a future version.