#30124: QuerySet.only() on reverse many-to-one relationship causes extra 
database
queries
-------------------------------------+-------------------------------------
               Reporter:  Beda       |          Owner:  nobody
  Kosata                             |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  2.1
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Using the following example models:

 {{{
 class WorkSet(models.Model):
     name = models.TextField(blank=True)

 class Work(models.Model):
     name = models.TextField(blank=True)
     work_set = models.ForeignKey(WorkSet, on_delete=models.CASCADE,
 related_name='works')
     extra_data = JSONField(default=dict, blank=True)
 }}}

 when I iterate over the Works related to a WorkSet {{{ ws }}} like this:

 {{{
 for work in ws.works.all().only('name'):
     print(work.name)
 }}}

 Not only one query is made to the database, but 1+N where N is the number
 of Works related to the WorkSet. In {{{ connection.queries }}} these
 queries look like this

 {{{
 'SELECT "test_work"."id", "test_work"."work_set_id" FROM "test_work" WHERE
 "test_work"."id" = 677931'
 }}}

 etc. That is - the ORM refetches the {{{ work_set_id }}} for each of the
 Works iterated over. If I change the loop to explicitly include {{{
 work_set_id }}}, only one query is run:

 {{{
 for work in ws.works.all().only('name', 'work_set_id'):
     print(work.name)
 }}}

 While this behavior makes some sense, I find it quite unexpected and a
 potential cause of nasty performance 'leaks'. It think that either the
 documentation should explicitly mention this case and how to work around
 it or better the ORM should automatically add the relationship key into
 the fetched fields.

 Please let me know if anything is unclear about this issue and if there is
 anything I can improve.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30124>
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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/049.39e8389288bf4cf84a8905996c8e9ce6%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to