Fixed #18304 -- Optimized save() when update_can_self_select=False
Databases with update_can_self_select = False (MySQL for example) generated non-necessary queries when saving a multitable inherited model, and when the save resulted in update.
This commit is contained in:
parent
6219591f2e
commit
d5c7f9efc3
|
@ -1015,6 +1015,12 @@ class SQLUpdateCompiler(SQLCompiler):
|
||||||
query.extra = {}
|
query.extra = {}
|
||||||
query.select = []
|
query.select = []
|
||||||
query.add_fields([query.model._meta.pk.name])
|
query.add_fields([query.model._meta.pk.name])
|
||||||
|
# Recheck the count - it is possible that fiddling with the select
|
||||||
|
# fields above removes tables from the query. Refs #18304.
|
||||||
|
count = query.count_active_tables()
|
||||||
|
if not self.query.related_updates and count == 1:
|
||||||
|
return
|
||||||
|
|
||||||
must_pre_select = count > 1 and not self.connection.features.update_can_self_select
|
must_pre_select = count > 1 and not self.connection.features.update_can_self_select
|
||||||
|
|
||||||
# Now we adjust the current query: reset the where clause and get rid
|
# Now we adjust the current query: reset the where clause and get rid
|
||||||
|
|
|
@ -275,3 +275,21 @@ class ModelInheritanceTests(TestCase):
|
||||||
def test_mixin_init(self):
|
def test_mixin_init(self):
|
||||||
m = MixinModel()
|
m = MixinModel()
|
||||||
self.assertEqual(m.other_attr, 1)
|
self.assertEqual(m.other_attr, 1)
|
||||||
|
|
||||||
|
def test_update_query_counts(self):
|
||||||
|
"""
|
||||||
|
Test that update queries do not generate non-necessary queries.
|
||||||
|
Refs #18304.
|
||||||
|
"""
|
||||||
|
c = Chef.objects.create(name="Albert")
|
||||||
|
ir = ItalianRestaurant.objects.create(
|
||||||
|
name="Ristorante Miron",
|
||||||
|
address="1234 W. Ash",
|
||||||
|
serves_hot_dogs=False,
|
||||||
|
serves_pizza=False,
|
||||||
|
serves_gnocchi=True,
|
||||||
|
rating=4,
|
||||||
|
chef=c
|
||||||
|
)
|
||||||
|
with self.assertNumQueries(6):
|
||||||
|
ir.save()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase
|
||||||
from django.db.models.signals import pre_save, post_save
|
from django.db.models.signals import pre_save, post_save
|
||||||
from .models import Person, Employee, ProxyEmployee, Profile, Account
|
from .models import Person, Employee, ProxyEmployee, Profile, Account
|
||||||
|
|
||||||
|
@ -123,9 +123,6 @@ class UpdateOnlyFieldsTests(TestCase):
|
||||||
self.assertEqual(len(pre_save_data), 0)
|
self.assertEqual(len(pre_save_data), 0)
|
||||||
self.assertEqual(len(post_save_data), 0)
|
self.assertEqual(len(post_save_data), 0)
|
||||||
|
|
||||||
# A bug in SQLUpdateCompiler prevents this test from succeeding on MySQL
|
|
||||||
# Require update_can_self_select for this test for now. Refs #18304.
|
|
||||||
@skipUnlessDBFeature('update_can_self_select')
|
|
||||||
def test_num_queries_inheritance(self):
|
def test_num_queries_inheritance(self):
|
||||||
s = Employee.objects.create(name='Sara', gender='F')
|
s = Employee.objects.create(name='Sara', gender='F')
|
||||||
s.employee_num = 1
|
s.employee_num = 1
|
||||||
|
|
Loading…
Reference in New Issue