Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
dc27f3ee
Kaydet (Commit)
dc27f3ee
authored
Mar 26, 2015
tarafından
Simon Charette
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #19259 -- Added group by selected primary keys support.
üst
8119876d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
34 additions
and
12 deletions
+34
-12
features.py
django/db/backends/base/features.py
+1
-0
features.py
django/db/backends/postgresql_psycopg2/features.py
+1
-0
compiler.py
django/db/models/sql/compiler.py
+12
-4
__init__.py
django/test/__init__.py
+3
-3
testcases.py
django/test/testcases.py
+10
-0
tests.py
tests/aggregation_regress/tests.py
+7
-5
No files found.
django/db/backends/base/features.py
Dosyayı görüntüle @
dc27f3ee
...
...
@@ -6,6 +6,7 @@ from django.utils.functional import cached_property
class
BaseDatabaseFeatures
(
object
):
gis_enabled
=
False
allows_group_by_pk
=
False
allows_group_by_selected_pks
=
False
# True if django.db.backends.utils.typecast_timestamp is used on values
# returned from dates() calls.
needs_datetime_string_cast
=
True
...
...
django/db/backends/postgresql_psycopg2/features.py
Dosyayı görüntüle @
dc27f3ee
...
...
@@ -3,6 +3,7 @@ from django.db.utils import InterfaceError
class
DatabaseFeatures
(
BaseDatabaseFeatures
):
allows_group_by_selected_pks
=
True
needs_datetime_string_cast
=
False
can_return_id_from_insert
=
True
has_real_datatype
=
True
...
...
django/db/models/sql/compiler.py
Dosyayı görüntüle @
dc27f3ee
...
...
@@ -136,10 +136,7 @@ class SQLCompiler(object):
# If the DB can group by primary key, then group by the primary key of
# query's main model. Note that for PostgreSQL the GROUP BY clause must
# include the primary key of every table, but for MySQL it is enough to
# have the main table's primary key. Currently only the MySQL form is
# implemented.
# MySQLism: however, columns in HAVING clause must be added to the
# GROUP BY.
# have the main table's primary key.
if
self
.
connection
.
features
.
allows_group_by_pk
:
# The logic here is: if the main model's primary key is in the
# query, then set new_expressions to that field. If that happens,
...
...
@@ -150,7 +147,18 @@ class SQLCompiler(object):
getattr
(
expr
.
output_field
,
'model'
)
==
self
.
query
.
model
):
pk
=
expr
if
pk
:
# MySQLism: Columns in HAVING clause must be added to the GROUP BY.
expressions
=
[
pk
]
+
[
expr
for
expr
in
expressions
if
expr
in
having
]
elif
self
.
connection
.
features
.
allows_group_by_selected_pks
:
# Filter out all expressions associated with a table's primary key
# present in the grouped columns. This is done by identifying all
# tables that have their primary key included in the grouped
# columns and removing non-primary key columns referring to them.
pks
=
{
expr
for
expr
in
expressions
if
hasattr
(
expr
,
'target'
)
and
expr
.
target
.
primary_key
}
aliases
=
{
expr
.
alias
for
expr
in
pks
}
expressions
=
[
expr
for
expr
in
expressions
if
expr
in
pks
or
getattr
(
expr
,
'alias'
,
None
)
not
in
aliases
]
return
expressions
def
get_select
(
self
):
...
...
django/test/__init__.py
Dosyayı görüntüle @
dc27f3ee
...
...
@@ -6,7 +6,7 @@ from django.test.client import Client, RequestFactory
from
django.test.testcases
import
(
TestCase
,
TransactionTestCase
,
SimpleTestCase
,
LiveServerTestCase
,
skipIfDBFeature
,
skipUnlessDBFeature
skipUnless
AnyDBFeature
,
skipUnless
DBFeature
)
from
django.test.utils
import
(
ignore_warnings
,
modify_settings
,
override_settings
,
override_system_checks
)
...
...
@@ -14,8 +14,8 @@ from django.test.utils import (ignore_warnings, modify_settings,
__all__
=
[
'Client'
,
'RequestFactory'
,
'TestCase'
,
'TransactionTestCase'
,
'SimpleTestCase'
,
'LiveServerTestCase'
,
'skipIfDBFeature'
,
'skipUnless
DBFeature'
,
'ignore_warnings'
,
'modify_sett
ings'
,
'override_settings'
,
'override_system_checks'
'skipUnless
AnyDBFeature'
,
'skipUnlessDBFeature'
,
'ignore_warn
ings'
,
'
modify_settings'
,
'
override_settings'
,
'override_system_checks'
]
# To simplify Django's test suite; not meant as a public API
...
...
django/test/testcases.py
Dosyayı görüntüle @
dc27f3ee
...
...
@@ -1051,6 +1051,16 @@ def skipUnlessDBFeature(*features):
)
def
skipUnlessAnyDBFeature
(
*
features
):
"""
Skip a test unless a database has any of the named features.
"""
return
_deferredSkip
(
lambda
:
not
any
(
getattr
(
connection
.
features
,
feature
,
False
)
for
feature
in
features
),
"Database doesn't support any of the feature(s):
%
s"
%
", "
.
join
(
features
)
)
class
QuietWSGIRequestHandler
(
WSGIRequestHandler
):
"""
Just a regular WSGIRequestHandler except it doesn't log to the standard
...
...
tests/aggregation_regress/tests.py
Dosyayı görüntüle @
dc27f3ee
...
...
@@ -7,10 +7,11 @@ from operator import attrgetter
from
django.contrib.contenttypes.models
import
ContentType
from
django.core.exceptions
import
FieldError
from
django.db
import
connection
from
django.db.models
import
(
F
,
Q
,
Avg
,
Count
,
Max
,
StdDev
,
Sum
,
Value
,
Variance
,
)
from
django.test
import
TestCase
,
skipUnlessDBFeature
from
django.test
import
TestCase
,
skipUnless
AnyDBFeature
,
skipUnless
DBFeature
from
django.test.utils
import
Approximate
from
django.utils
import
six
...
...
@@ -1011,7 +1012,7 @@ class AggregationTests(TestCase):
# Check that the query executes without problems.
self
.
assertEqual
(
len
(
qs
.
exclude
(
publisher
=-
1
)),
6
)
@skipUnless
DBFeature
(
"allows_group_by_pk"
)
@skipUnless
AnyDBFeature
(
'allows_group_by_pk'
,
'allows_group_by_selected_pks'
)
def
test_aggregate_duplicate_columns
(
self
):
# Regression test for #17144
...
...
@@ -1041,7 +1042,7 @@ class AggregationTests(TestCase):
]
)
@skipUnless
DBFeature
(
"allows_group_by_pk"
)
@skipUnless
AnyDBFeature
(
'allows_group_by_pk'
,
'allows_group_by_selected_pks'
)
def
test_aggregate_duplicate_columns_only
(
self
):
# Works with only() too.
results
=
Author
.
objects
.
only
(
'id'
,
'name'
)
.
annotate
(
num_contacts
=
Count
(
'book_contact_set'
))
...
...
@@ -1067,13 +1068,14 @@ class AggregationTests(TestCase):
]
)
@skipUnless
DBFeature
(
"allows_group_by_pk"
)
@skipUnless
AnyDBFeature
(
'allows_group_by_pk'
,
'allows_group_by_selected_pks'
)
def
test_aggregate_duplicate_columns_select_related
(
self
):
# And select_related()
results
=
Book
.
objects
.
select_related
(
'contact'
)
.
annotate
(
num_authors
=
Count
(
'authors'
))
_
,
_
,
grouping
=
results
.
query
.
get_compiler
(
using
=
'default'
)
.
pre_sql_setup
()
self
.
assertEqual
(
len
(
grouping
),
1
)
# In the case of `group_by_selected_pks` we also group by contact.id because of the select_related.
self
.
assertEqual
(
len
(
grouping
),
1
if
connection
.
features
.
allows_group_by_pk
else
2
)
self
.
assertIn
(
'id'
,
grouping
[
0
][
0
])
self
.
assertNotIn
(
'name'
,
grouping
[
0
][
0
])
self
.
assertNotIn
(
'contact'
,
grouping
[
0
][
0
])
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment