Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Optimize MySQL model.save() in inheritance cases #61

Closed
wants to merge 1 commit into from

1 participant

Anssi Kääriäinen
Anssi Kääriäinen
Owner

MySQL generated non-necessary queries when saving a multitable
inherited model, and when the save resulted in update.

This issue is tracked in ticket #18304

Anssi Kääriäinen
Owner

cramm raised a good point in #django-dev - the issue is described as MySQL specific, but it is actually about "update_can_self_select". MySQL just happens to be the only core database backend with that problem. I will update the commit message.

Anssi Kääriäinen 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.
317e4dc
Anssi Kääriäinen
Owner

Pulled in manually in d5c7f9e

Anssi Kääriäinen akaariai closed this May 22, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

May 13, 2012
Anssi Kääriäinen 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.
317e4dc
This page is out of date. Refresh to see the latest.
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
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.