#36050 closed Bug (fixed)
Cannot resolve OuterRef to CompositePrimaryKey
| Reported by: | Jacob Walls | Owned by: | Csirmaz Bendegúz |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Release blocker | Keywords: | subquery |
| Cc: | Csirmaz Bendegúz | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
With CompositePrimaryKey, using OuterRef("pk") in a subquery raises ValueError. Not certain if this is a release blocker or a new feature. If it's a new feature, we might want to document that it's not currently supported.
-
tests/composite_pk/test_filter.py
diff --git a/tests/composite_pk/test_filter.py b/tests/composite_pk/test_filter.py index 7e361c5925..c3dfc8d44b 100644
a b 1 from django.db.models import OuterRef, Subquery 1 2 from django.test import TestCase 2 3 3 4 from .models import Comment, Tenant, User … … class CompositePKFilterTests(TestCase): 54 55 with self.subTest(lookup=lookup, count=count): 55 56 self.assertEqual(User.objects.filter(**lookup).count(), count) 56 57 58 def test_outer_ref_pk(self): 59 qs = Comment.objects.filter( 60 id__gt=Subquery(Comment.objects.filter(pk=OuterRef("pk")).values("id")[:1]) 61 ) 62 self.assertEqual(qs.count(), 0) 63 57 64 def test_order_comments_by_pk_asc(self): 58 65 self.assertSequenceEqual( 59 66 Comment.objects.order_by("pk"),
File "/Users/.../django/django/db/models/fields/tuple_lookups.py", line 32, in get_prep_lookup
self.check_rhs_is_tuple_or_list()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/Users/.../django/django/db/models/fields/tuple_lookups.py", line 39, in check_rhs_is_tuple_or_list
raise ValueError(
f"{self.lookup_name!r} lookup of {lhs_str} must be a tuple or a list"
)
ValueError: 'exact' lookup of 'pk' must be a tuple or a list
Adjusting the guard that raises ValueError to also accept ResolvedOuterRef leads to a more interesting failure:
File "/Users/.../django/django/db/models/expressions.py", line 1162, in as_sql
val = output_field.get_db_prep_value(val, connection=connection)
File "/Users/.../django/django/db/models/fields/related.py", line 1161, in get_db_prep_value
return self.target_field.get_db_prep_value(value, connection, prepared)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/.../django/django/db/models/fields/__init__.py", line 2819, in get_db_prep_value
value = self.get_prep_value(value)
File "/Users/.../django/django/db/models/fields/__init__.py", line 2129, in get_prep_value
raise e.__class__(
"Field '%s' expected a number but got %r." % (self.name, value),
) from e
TypeError: Field 'id' expected a number but got Col(composite_pk_comment, composite_pk.Comment.tenant).
Change History (11)
comment:1 by , 11 months ago
| Cc: | added |
|---|---|
| Severity: | Normal → Release blocker |
| Triage Stage: | Unreviewed → Accepted |
| Type: | New feature → Bug |
comment:5 by , 10 months ago
| Patch needs improvement: | set |
|---|
comment:6 by , 10 months ago
| Patch needs improvement: | unset |
|---|
comment:7 by , 10 months ago
| Patch needs improvement: | set |
|---|
comment:8 by , 10 months ago
| Patch needs improvement: | unset |
|---|
comment:9 by , 10 months ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
Note:
See TracTickets
for help on using tickets.
Thank you Jacob
Marking as a release blocker. I think we might be able to resolve this but if not, agree we might want to document it within the not supported section.