Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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.
  • Loading branch information...
commit d5c7f9efc3702888b556cbf932116421b464e8b8 1 parent 6219591
Anssi Kääriäinen authored
6  django/db/models/sql/compiler.py
@@ -1015,6 +1015,12 @@ def pre_sql_setup(self):
1015 1015
         query.extra = {}
1016 1016
         query.select = []
1017 1017
         query.add_fields([query.model._meta.pk.name])
  1018
+        # Recheck the count - it is possible that fiddling with the select
  1019
+        # fields above removes tables from the query. Refs #18304.
  1020
+        count = query.count_active_tables()
  1021
+        if not self.query.related_updates and count == 1:
  1022
+            return
  1023
+
1018 1024
         must_pre_select = count > 1 and not self.connection.features.update_can_self_select
1019 1025
 
1020 1026
         # Now we adjust the current query: reset the where clause and get rid
18  tests/modeltests/model_inheritance/tests.py
@@ -275,3 +275,21 @@ def test_multiple_table(self):
275 275
     def test_mixin_init(self):
276 276
         m = MixinModel()
277 277
         self.assertEqual(m.other_attr, 1)
  278
+
  279
+    def test_update_query_counts(self):
  280
+        """
  281
+        Test that update queries do not generate non-necessary queries.
  282
+        Refs #18304.
  283
+        """
  284
+        c = Chef.objects.create(name="Albert")
  285
+        ir = ItalianRestaurant.objects.create(
  286
+            name="Ristorante Miron",
  287
+            address="1234 W. Ash",
  288
+            serves_hot_dogs=False,
  289
+            serves_pizza=False,
  290
+            serves_gnocchi=True,
  291
+            rating=4,
  292
+            chef=c
  293
+        )
  294
+        with self.assertNumQueries(6):
  295
+            ir.save()
5  tests/modeltests/update_only_fields/tests.py
... ...
@@ -1,6 +1,6 @@
1 1
 from __future__ import absolute_import
2 2
 
3  
-from django.test import TestCase, skipUnlessDBFeature
  3
+from django.test import TestCase
4 4
 from django.db.models.signals import pre_save, post_save
5 5
 from .models import Person, Employee, ProxyEmployee, Profile, Account
6 6
 
@@ -123,9 +123,6 @@ def post_save_receiver(**kwargs):
123 123
         self.assertEqual(len(pre_save_data), 0)
124 124
         self.assertEqual(len(post_save_data), 0)
125 125
 
126  
-    # A bug in SQLUpdateCompiler prevents this test from succeeding on MySQL
127  
-    # Require update_can_self_select for this test for now. Refs #18304.
128  
-    @skipUnlessDBFeature('update_can_self_select')
129 126
     def test_num_queries_inheritance(self):
130 127
         s = Employee.objects.create(name='Sara', gender='F')
131 128
         s.employee_num = 1

0 notes on commit d5c7f9e

Please sign in to comment.
Something went wrong with that request. Please try again.