Opened 3 days ago
Last modified 20 hours ago
#36050 assigned Bug
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: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
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 (5)
comment:1 by , 2 days ago
Cc: | added |
---|---|
Severity: | Normal → Release blocker |
Triage Stage: | Unreviewed → Accepted |
Type: | New feature → Bug |
comment:5 by , 20 hours ago
Patch needs improvement: | set |
---|
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.