Hello, I’ve just noticed that when I do
MyModel.objects.select_for_update().count() != 0
it runs successfully. However, when I do
MyModel.objects.select_for_update().exists()
I get an error select_for_update cannot be used outside of a transaction.
I checked the queries that django made and they are as follows:
SELECT COUNT(*) AS "__count" FROM "example_mymodel" # .count()
SELECT (1) AS "a" FROM "example_mymodel" LIMIT 1 FOR UPDATE # .exists()
I tested it by creating a completely new app in my existing django project (django==3.2.10 + PostgreSQL 12.0.1) and this is the model I used:
class MyModel(models.Model):
my_field = models.CharField(max_length=256)
However, when I created a completely new django project (django==3.2.10 + SQLite 3.31.1) with the same app and model, the .exists() query passed without wrapping it with transaction.atomic(). This is the query in the second test
SELECT (1) AS "a" FROM "example_mymodel" LIMIT 1
Note that it doesn’t contain FOR UPDATE.
All tests were done via ./manage.py shell and looked up with django.connection.queries.
Is this expected? Why is there such discrepancy between .count() and .exists() or different databases?