#34229: "no such column" when combining FilteredRelation and multi-table
inheritance models
-------------------------------------+-------------------------------------
     Reporter:  Javier Ayres         |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  4.1
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  filteredrelation     |             Triage Stage:  Accepted
  such column                        |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

 After further investigation this issue is fundamentally the same as the
 one that we currently error out about when trying to do

 {{{#!python
 Author.objects.annotate(
     book_editor=FilteredRelation(
         "book",
         condition=Q(book__editor__name__icontains="b"),
     ),
 )
 }}}

 Which we currently out with `FilteredRelation's condition doesn't support
 nested relations deeper than the relation_name (got
 'book__editor__name__icontains' for 'book').` (see
 
[https://github.com/django/django/blob/c813fb327cb1b09542be89c5ceed367826236bc2/tests/filtered_relation/tests.py#L632-L644
 test] and
 
[https://github.com/django/django/blob/c813fb327cb1b09542be89c5ceed367826236bc2/django/db/models/sql/query.py#L1597-L1601
 origin])

 The rationale behind this classification is that `student__superuser` is
 actually an alias for `student__user_ptr__superuser` so the reported case
 here

 {{{#!python
 School.objects.annotate(
     superusers=FilteredRelation(
         'student',
         condition=Q(
             student__superuser=True,
         ),
     )
 )
 }}}

 Is an alias for

 {{{#!python
 School.objects.annotate(
     superusers=FilteredRelation(
         'student',
         condition=Q(
             student__user__ptr__superuser=True,
         ),
     )
 )
 }}}

 The latter is
 
[https://github.com/django/django/blob/c813fb327cb1b09542be89c5ceed367826236bc2/django/db/models/sql/query.py#L1597-L1601
 caught by the depth check] but not the former because the logic is not
 aware of MTI aliasing

 To summarize, we should likely adapt the depth check to consider MTI
 aliasing to address the bug reported here (so it doesn't reach the db and
 result in an opaque SQL failure) and we could then consider a ''new
 feature'' to generically support `relation__join` references in
 `condition` (haven't invested much time in figuring out what that would
 even mean.

 I personally don't think that it would make sense to implement the latter
 as this ''problem'' can be circumvented by targeting the relation where
 the field lives. In the provided test case that means doing

 {{{#!diff
 diff --git a/tests/filtered_relation/tests.py
 b/tests/filtered_relation/tests.py
 index 9d38593065..b269ed786d 100644
 --- a/tests/filtered_relation/tests.py
 +++ b/tests/filtered_relation/tests.py
 @@ -832,7 +832,8 @@ def test_condition_spans_mti(self):
          self.assertSequenceEqual(
              Editor.objects.annotate(
                  small_libraries=FilteredRelation(
 -                    "libraries", condition=Q(libraries__small=True)
 +                    "libraries__location_ptr",
 +                    condition=Q(libraries__location_ptr__small=True),
                  ),
              )
              .filter(
 }}}

 And in the user's reported case that means chaining filtered relations
 which is supported

 {{{#!python
 School.objects.annotate(
     superstudents=FilteredRelation(
         'student',
         condition=Q(
             student__superstudent=True,
         ),
     )
     superusers=FilteredRelation(
         'superstudents__user_ptr',
         condition=Q(
             superstudents__user_ptr__superuser=True,
         ),
     ),
     superstudents_count=Count(
         'superusers'
     ),
 )
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34229#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070187b51a258d-93d2e890-588c-460d-970b-a18c9e28cdae-000000%40eu-central-1.amazonses.com.

Reply via email to