question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Make django's QuerySet.update().order_by('') work for MySQL

See original GitHub issue

Summary: Since MySQL does not support a defered unique constraint (like some other databases do), it would be great if this package could supply a way to update with an order_by clause. More here. For example the

UPDATE t SET id = id + 1 ORDER BY id DESC;

example from the MySQL docs is currently not working with Django 2.2 and still gives an IntegrityError for the unique key.

The query that is executed is:

query = 'UPDATE `model` SET `integerfield` = (`model`.`integerfield` + %s) WHERE (`model`.`date` = %s AND `model`.`integerfield` >= %s)'
args = (1, '2020-04-26',  2)

As you can see the ORDER_BY, which should make it work, is omitted in the query, while it is in the Django code:

                qs_to_increase = self.get_indexing_queryset().filter(
                    integerfield__gte=self.integerfield).order_by('-integerfield')

                # apply changes after getting the qs!
                qs_to_increase.update(integerfield=F('integerfield') + 1)

Django Version: Django 2.2

Database and version used: MySQL 8.0.20-0ubuntu0.19.10.1

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
adamchainzcommented, May 13, 2020

Thanks for the ticket, I’ve CC’d myself and added a reply.

Your instrumentation looks about right. You don’t need the table name per se, and should use += to actually mutate the local SQL variable: sql += ' ORDER BY column_name'.

0reactions
gabn88commented, Mar 1, 2021

I just wanted to follow up on this, since upgrading to Django 3.1 breaks this way of solving it.

It is because of this commit (I believe): https://github.com/django/django/commit/a19505eb2ecd4a07ff39f3f66898e68b69d0e680#diff-dabf20e4ab58ae26d868833eefa64d93896519623d676bdb47bee47b0b6b5543 Before performing the database execution a simple “SELECT VERSION()” is issued if the connection is newly initiated. If you apply the database instrumentation hook, it will fail for not finding the table.

Fixed it by applying a

    if sql != 'SELECT VERSION()':

before I change the sql.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to select a record and update it, with a single queryset in ...
Use the queryset object update method: MyModel.objects.filter(pk=some_value).update(field1='some value').
Read more >
#20708 (QuerySet.update() ignores order_by() clause) – Django
This is a problem with MySQL, because for bulk updates on a unique key, you must specify the working order, otherwise the above...
Read more >
Django QuerySet - Order By - W3Schools
Order By. To sort QuerySets, Django uses the order_by() method: · Descending Order. By default, the result is sorted ascending (the lowest value...
Read more >
Django Tutorial Part 3: Using models - Learn web development
The reverse() function above is able to "reverse" your URL mapper (in the above case named 'model-detail-view') in order to create a URL...
Read more >
Filtering - Django REST framework
The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found