Skip to content

fix(queryset): make distinct().count() ignore join-duplicated rows#2255

Open
Sanjays2402 wants to merge 1 commit into
tortoise:developfrom
Sanjays2402:fix/distinct-count-join-duplicates
Open

fix(queryset): make distinct().count() ignore join-duplicated rows#2255
Sanjays2402 wants to merge 1 commit into
tortoise:developfrom
Sanjays2402:fix/distinct-count-join-duplicates

Conversation

@Sanjays2402

Copy link
Copy Markdown

Closes #2178

Description

QuerySet.count() always emitted COUNT(*), which counts every row the query produces. distinct() only sets SELECT DISTINCT on the row query, so when a filter spans an m2m (or any other row-multiplying join) the returned objects were de-duplicated but the count was not. CountQuery now receives the _distinct flag and counts distinct primary keys; grouped queries keep the existing windowed COUNT(*).

Motivation and Context

Fixes #2178: Model.filter(m2m_field__name__in=[...]).distinct() returns 1 object but .count() returned 3.

How Has This Been Tested?

Added test_distinct_count_with_m2m_join in tests/test_queryset.py. It fails on develop (assert 3 == 1) and passes with the fix. Full suite run on SQLite is unchanged otherwise (1789 -> 1790 passed, same 3 pre-existing environment failures before and after).

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added the changelog accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

QuerySet.count() always emitted COUNT(*), which counts every row the
query produces. When the queryset is distinct() and the filter spans a
m2m (or any other row-multiplying join), the returned objects are
de-duplicated by the SELECT DISTINCT but the count was not, so count()
reported more rows than the queryset actually yields.

CountQuery now receives the _distinct flag and counts distinct primary
keys instead. Grouped queries keep the existing windowed COUNT(*).

Closes tortoise#2178
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

count() 方法在多对多条件查询distinct()后,会返回所有的数,不是distinct()后实际的数量

1 participant