diff options
author | davidchorpash <dchorpash@doctorondemand.com> | 2020-06-19 22:55:03 -0600 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-07-08 11:43:50 +0200 |
commit | 779e615e362108862f1681f965ee9e4f1d0ae6d2 (patch) | |
tree | 631a909a539adf33193a5dc1d6d5ee086d11be6e /tests/update | |
parent | 060576b0abac460d72714e300aa709d1e7a87dd7 (diff) | |
download | django-779e615e362108862f1681f965ee9e4f1d0ae6d2.tar.gz |
Fixed #31573 -- Made QuerySet.update() respect ordering on MariaDB/MySQL.
Diffstat (limited to 'tests/update')
-rw-r--r-- | tests/update/models.py | 4 | ||||
-rw-r--r-- | tests/update/tests.py | 40 |
2 files changed, 43 insertions, 1 deletions
diff --git a/tests/update/models.py b/tests/update/models.py index 7861987604..98f40a8603 100644 --- a/tests/update/models.py +++ b/tests/update/models.py @@ -41,3 +41,7 @@ class Foo(models.Model): class Bar(models.Model): foo = models.ForeignKey(Foo, models.CASCADE, to_field='target') m2m_foo = models.ManyToManyField(Foo, related_name='m2m_foo') + + +class UniqueNumber(models.Model): + number = models.IntegerField(unique=True) diff --git a/tests/update/tests.py b/tests/update/tests.py index abf4db11d9..90844ccb6f 100644 --- a/tests/update/tests.py +++ b/tests/update/tests.py @@ -1,9 +1,12 @@ +import unittest + from django.core.exceptions import FieldError +from django.db import IntegrityError, connection, transaction from django.db.models import Count, F, Max from django.db.models.functions import Concat, Lower from django.test import TestCase -from .models import A, B, Bar, D, DataPoint, Foo, RelatedPoint +from .models import A, B, Bar, D, DataPoint, Foo, RelatedPoint, UniqueNumber class SimpleTest(TestCase): @@ -199,3 +202,38 @@ class AdvancedTests(TestCase): with self.subTest(annotation=annotation): with self.assertRaisesMessage(FieldError, msg): RelatedPoint.objects.annotate(new_name=annotation).update(name=F('new_name')) + + +@unittest.skipUnless( + connection.vendor == 'mysql', + 'UPDATE...ORDER BY syntax is supported on MySQL/MariaDB', +) +class MySQLUpdateOrderByTest(TestCase): + """Update field with a unique constraint using an ordered queryset.""" + @classmethod + def setUpTestData(cls): + UniqueNumber.objects.create(number=1) + UniqueNumber.objects.create(number=2) + + def test_order_by_update_on_unique_constraint(self): + tests = [ + ('-number', 'id'), + (F('number').desc(), 'id'), + (F('number') * -1, 'id'), + ] + for ordering in tests: + with self.subTest(ordering=ordering), transaction.atomic(): + updated = UniqueNumber.objects.order_by(*ordering).update( + number=F('number') + 1, + ) + self.assertEqual(updated, 2) + + def test_order_by_update_on_unique_constraint_annotation(self): + # Ordering by annotations is omitted because they cannot be resolved in + # .update(). + with self.assertRaises(IntegrityError): + UniqueNumber.objects.annotate( + number_inverse=F('number').desc(), + ).order_by('number_inverse').update( + number=F('number') + 1, + ) |