Changes between Initial Version and Version 6 of Ticket #28586


Ignore:
Timestamp:
Sep 13, 2017, 4:10:57 AM (7 years ago)
Author:
Gordon Wrigley
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #28586

    • Property Cc Adam Johnson Ryan Hiebert added
  • Ticket #28586 – Description

    initial v6  
    1 When accessing a 2one field (foreign key in the forward direction and one2one in either direction) on a model instance, if the fields value has not yet been loaded then Django should prefetch the field for all model instances loaded by the same queryset as the current model instance.
     1When accessing a 2one field (foreign key in the forward direction and one2one in either direction) on a model instance, if the field's value has not yet been loaded then Django should prefetch the field for all model instances loaded by the same queryset as the current model instance.
    22
    33There has been some discussion of this on the mailing list https://groups.google.com/forum/#!topic/django-developers/EplZGj-ejvg
    44
    5 Currently when accessing an uncached 2one field Django will automatically fetch the missing value from the Database. When this occurs in a loop it creates 1+N query problems. Consider the following snippet:
     5Currently when accessing an uncached 2one field, Django will automatically fetch the missing value from the Database. When this occurs in a loop it creates 1+N query problems. Consider the following snippet:
    66
    77{{{#!python
     
    2626* It is very difficult for libraries like the admin and Django Rest Framework to automatically generate correct prefetch_related clauses.
    2727
    28 The proposal is on the first iteration of the loop in the example above, when we first access a choice's question field instead of fetching the question for just that choice, speculatively fetch the questions for all the choices returned by the queryset.
     28The proposal is on the first iteration of the loop in the example above, when we first access a choice's question field, instead of fetching the question for just that choice, speculatively fetch the questions for all the choices returned by the queryset.
    2929This change results in the first snippet having the same database behavior as the second while reducing or eliminating all of the noted usability issues.
    3030
    3131Some important points:
    32 * 2many fields are not changed at all by this proposal as I can't think of a reasonable way of deciding which of the many to fetch
    33 * Because these are 2one fields the generated queries can't have more result rows than the original query and may have less.
    34 * This feature will never result in more database queries.
    35 * It will not change the DB behavior of code which is full covered by prefetch_related (and select_related) calls at all.
     32* 2many fields are not changed at all by this proposal as I can't think of a reasonable way of deciding which of the many to fetch.
     33* Because these are 2one fields the generated queries can't have more result rows than the original query and may have less. This eliminates any concern about a multiplicative query size explosion.
     34* This feature will never result in more database queries as a prefetch will only be issued where the ORM was already going to fetch a related object.
     35* Because it is triggered by fetching missing related objects it will not at all change the DB behavior of code which is full covered by prefetch_related (and select_related) calls.
    3636* This will inherently chain across relations like choice.question.author, the conditions above still hold under such chaining.
    3737* It may result in larger data transfer between the database and Django in some situations.
    3838
    39 On that last point an example would be this:
     39An example of that last point is:
    4040{{{#!python
    4141qs = Choice.objects.all()
Back to Top