Hello,
Context
First of all, I was updating my projets from Django 5.1 to Django 5.2, and I noticed that some of my unit tests - that assert the number of queries must not exceed a certain limit - failed.
Few minutes later, I found out that in Django 5.2 in order to fix this issue #35712 the following commit #c6a4f85 has been suggested.
If you pay attention to line 141, when I call for example the full_clean() method, each constraint of my model is now checked within a transaction.atomic
like this :
1. SAVEPOINT "s8423710464_x7170"
2. SELECT 1 AS "_check" WHERE COALESCE((('created' = 'completed' OR '' = '') AND NOT ('created' = 'completed' AND '' = '')), true)
3. RELEASE SAVEPOINT "s8423710464_x7170"
Question
So as a Django newbie my question is:
Sin we open and close a transaction.atomic for each constraint. Is there a potentiel performance issue as we increased considerably the number of queries ?
Does transaction.atomic generates like light-weighted queries so actually it’s not an issue ?
Best regards
1 Like
Hello @diepvu-pi,
Creating a save point per checked constraint should not have a significant impact on performance in this case given most model form validation perform much costlier queries such as the constraint check itself, foreign key choices validation, and the eventual model save which might involve save points of its own.
It’s important to note that unless you have atomic views enabled, form cleaning usually does not take place within a transaction and thus no save points would normally be created (notice the usage of nullcontext
when this is the case). What you are experiencing in your tests is most likely a side effect of using TestCase
which wraps each tests in a transaction for easier state isolation management (and thus requires the usage of savepoints for nested transaction.atomic
) and might not happen in a non-testing scenario.
In summary, unless you are explicitly running model form validation in a transaction, which you normally wouldn’t, you should not encounter these save points outside of your tests.
The code could likely be adjusted to be a bit smarter in this case by only wrapping in atomic
when RawSQL
nodes are involved but we’d need to have a demonstration that this effectively has a performance impact in real world scenario (read non-testing one) as it would induce complexity.
4 Likes