#30719: Unable to use OuterRef(Expression(...))
-------------------------------------+-------------------------------------
               Reporter:  Matthew    |          Owner:  nobody
  Schinckel                          |
                   Type:  New        |         Status:  new
  feature                            |
              Component:  Database   |        Version:  master
  layer (models, ORM)                |       Keywords:  Subquery, OuterRef,
               Severity:  Normal     |  Expression
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  1
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Whilst refactoring some code today, I noticed I had the following code in
 a queryset method:


 {{{
 staff = Person.objects.filter(
     first_name__iexact=OuterRef('_first_name'),
     ...
 )

 return self.annotate(
     _first_name=Func(F('data'), Value('FirstName'),
 function='JSONB_EXTRACT_PATH_TEXT', output_field=models.TextField()
 ).annotate(
     candidates=Array(staff.values('pk'))
 )
 }}}


 It's an annoyance to have to annotate on the expression to the outer
 queryset, and then reference it in the inner queryset. It's also forcing
 the database to do more work, because the SQL that is generated will
 result in the expression being evaluated multiple times.

 Instead, it will be much nicer to write:

 {{{
 staff = Person.objects.filter(
     first_name__iexact=OuterRef(
         Func(OuterRef('data'), Value('FirstName'),
 function='JSONB_EXTRACT_PATH_TEXT', output_field=models.TextField()
     )
 )

 return self.annotate(candidates=Array(staff.values('pk')))
 }}}

 (Note the second use of OuterRef there because we are referring to the
 `data` from the outer queryset).

 I believe the only change that is required to enable this is in
 OuterRef.resolve_expression (and I have a working prototype on my 1.11
 codebase).


 Does this seem like a sane change to the functionality?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30719>
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/052.1dedb39d34b2e987439093a97460e376%40djangoproject.com.

Reply via email to