#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 , 3 years ago
comment:2 by , 3 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 , 3 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 , 3 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 , 3 years ago
Component: | Database layer (models, ORM) → Documentation |
---|---|
Has patch: | set |
Resolution: | invalid |
Status: | closed → new |
Type: | Bug → Cleanup/optimization |
comment:6 by , 3 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_arguments
and 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?