#32888 closed Cleanup/optimization (fixed)
Document that select_for_update() doesn't lock tables when their columns are not selected.
| Reported by: | Hannes Ljungberg | Owned by: | Hannes Ljungberg |
|---|---|---|---|
| Component: | Documentation | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
The existing test "test_for_update_of_self_when_self_is_not_selected" can be extended to demonstrate this behaviour:
diff --git a/tests/select_for_update/tests.py b/tests/select_for_update/tests.py
index 705975b760..00fa102d33 100644
--- a/tests/select_for_update/tests.py
+++ b/tests/select_for_update/tests.py
@@ -240,9 +240,15 @@ class SelectForUpdateTests(TransactionTestCase):
select_for_update(of=['self']) when the only columns selected are from
related tables.
"""
- with transaction.atomic():
+ with transaction.atomic(), CaptureQueriesContext(connection) as ctx:
values = list(Person.objects.select_related('born').select_for_update(of=('self',)).values('born__name'))
self.assertEqual(values, [{'born__name': self.city1.name}])
+ if connection.features.select_for_update_of_column:
+ expected = ['select_for_update_person"."id']
+ else:
+ expected = ['select_for_update_person']
+ expected = [connection.ops.quote_name(value) for value in expected]
+ self.assertTrue(self.has_for_update_sql(ctx.captured_queries, of=expected))
@skipUnlessDBFeature('has_select_for_update_nowait')
def test_nowait_raises_error_on_block(self):
Change History (8)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
IMO this is an expected behavior, we changed it in the PR.
follow-up: 4 comment:3 by , 4 years ago
Thanks, missed that PR. IMO it's a bit unexpected that the selected fields might end up affecting FOR UPDATE. What do you think about adding a small note about this in the docs?
comment:4 by , 4 years ago
Replying to Hannes Ljungberg:
Thanks, missed that PR. IMO it's a bit unexpected that the selected fields might end up affecting
FOR UPDATE. What do you think about adding a small note about this in the docs?
Sure, feel-free to propose a clarification.
comment:5 by , 4 years ago
| Component: | Database layer (models, ORM) → Documentation |
|---|---|
| Has patch: | set |
| Resolution: | invalid |
| Status: | closed → new |
| Type: | Bug → Cleanup/optimization |
comment:6 by , 4 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
| Summary: | Using select_for_update with self as an of-argument gets dropped when only selecting fields on related model → Document that select_for_update() doesn't lock tables when their columns are not selected. |
| Triage Stage: | Unreviewed → Accepted |
Tried to understand what's happening in
SQLCompiler.get_select_for_update_of_argumentsand it appears like it's dependant on what tables and columns have been SELECT:ed. Looks like we only need to do this because Oracle want columns instead of tables. I wonder if we could base this on the JOIN:ed tables instead and grab the column from the predicate for Oracle?