Opened 3 days ago
Last modified 45 hours ago
#36149 assigned Bug
Composite primary key subquery lookup prevent usage or specify fields and are not implemented for exact
Reported by: | Simon Charette | Owned by: | Simon Charette |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Csirmaz Bendegúz | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
I started playing with tuple lookup support for composite primary key and I noticed two main problems.
First pk__in=query
lookups completely disallow specifying which fields should be used in the select clause of the right-hand-side and implicitly set them to the left-hand-side name which assumes the same set of left-hand-side field name is shared by the right-hand-side which is a bad assumption
-
tests/composite_pk/models/tenant.py
diff --git a/tests/composite_pk/models/tenant.py b/tests/composite_pk/models/tenant.py index 6286ed2354..c85869afa7 100644
a b class Comment(models.Model): 44 44 related_name="comments", 45 45 ) 46 46 text = models.TextField(default="", blank=True) 47 integer = models.IntegerField(default=0) 47 48 48 49 49 50 class Post(models.Model): -
tests/composite_pk/test_filter.py
diff --git a/tests/composite_pk/test_filter.py b/tests/composite_pk/test_filter.py index fe942b9e5b..78383655a0 100644
a b def test_filter_comments_by_pk_in(self): 182 182 Comment.objects.filter(pk__in=pks).order_by("pk"), objs 183 183 ) 184 184 185 def test_filter_comments_by_pk_in_subquery(self): 186 self.assertSequenceEqual( 187 Comment.objects.filter( 188 pk__in=Comment.objects.filter(pk=self.comment_1.pk), 189 ), 190 [self.comment_1], 191 ) 192 self.assertSequenceEqual( 193 Comment.objects.filter( 194 pk__in=Comment.objects.filter(pk=self.comment_1.pk).values( 195 "tenant_id", "id" 196 ), 197 ), 198 [self.comment_1], 199 ) 200 self.comment_2.integer = self.comment_1.id 201 self.comment_2.save() 202 self.assertSequenceEqual( 203 Comment.objects.filter( 204 pk__in=Comment.objects.values("tenant_id", "integer"), 205 ), 206 [self.comment_1], 207 ) 208 185 209 def test_filter_comments_by_user_and_order_by_pk_asc(self): 186 210 self.assertSequenceEqual( 187 211 Comment.objects.filter(user=self.user_1).order_by("pk"),
Allowing fields to be specified requires lifting a QuerySet
resolving time constraint which was entirely by-passable by passing queryset.query
instead as the right-hand-side.
The tuple exact lookup should also allow querysets with a single element to be specified as right-hand-side which is currently disallowed
-
tests/composite_pk/test_filter.py
diff --git a/tests/composite_pk/test_filter.py b/tests/composite_pk/test_filter.py index fe942b9e5b..78383655a0 100644
a b def test_non_outer_ref_subquery(self): 450 474 with self.assertRaisesMessage(ValueError, msg): 451 475 Comment.objects.filter(pk=pk) 452 476 477 def test_filter_comments_by_pk_exact_subquery(self): 478 self.assertSequenceEqual( 479 Comment.objects.filter( 480 pk=Comment.objects.filter(pk=self.comment_1.pk)[:1], 481 ), 482 [self.comment_1], 483 ) 484 self.assertSequenceEqual( 485 Comment.objects.filter( 486 pk__in=Comment.objects.filter(pk=self.comment_1.pk).values( 487 "tenant_id", "id" 488 )[:1], 489 ), 490 [self.comment_1], 491 ) 492 self.comment_2.integer = self.comment_1.id 493 self.comment_2.save() 494 self.assertSequenceEqual( 495 Comment.objects.filter( 496 pk__in=Comment.objects.values("tenant_id", "integer"), 497 )[:1], 498 [self.comment_1], 499 ) 500 453 501 def test_outer_ref_not_composite_pk(self): 454 502 subquery = Comment.objects.filter(pk=OuterRef("id")).values("id") 455 503 queryset = Comment.objects.filter(id=Subquery(subquery))
Lastly lifting the constraint that prevented subqueries returning more than one column from being used as a right-hand-side required adjusting the existing exact
and in
lookup logic to disallow left-hand-side and right-hand-side with mismatching number of fields.
Change History (3)
comment:1 by , 3 days ago
Cc: | added |
---|---|
Has patch: | unset |
Owner: | set to |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 3 days ago
Has patch: | set |
---|
comment:3 by , 45 hours ago
Patch needs improvement: | set |
---|
Thank you!