#30079: Prefetch cache should be aware of database source and .using() should 
not
always trigger a new query
-------------------------------------+-------------------------------------
               Reporter:  Mike       |          Owner:  nobody
  Lissner                            |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  2.1
  layer (models, ORM)                |       Keywords:  prefetch,
               Severity:  Normal     |  multidatabase
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 I've been poking around the darker edges of multidatabase prefetching and
 I discovered a strange pattern. When you have cached prefetch values,
 they're not aware of which database they came from:

 {{{
 # This runs zero queries
 In [62]: pizzas =
 Pizza.objects.filter(pk=17).prefetch_related('toppings').using('replica')

 # This runs two, as expected
 In [63]: pizza0 = pizzas[0]

 # This runs zero, even though it normally would come from "default" and
 the cache came from "replica"
 In [64]: pizza0.toppings.all()
 Out[64]: [<Topping 1: Cheese>, <Topping 2: Bacon>]

 # This runs one query, even though this data should already be populated.
 In [65]: pizza0.toppings.all().using('replica')
 Out[65]: [<Topping 1: Cheese>, <Topping 2: Bacon>]
 }}}

 I was pretty surprised and confused that adding the using() method on the
 last line above busted the cache even when the database selected was the
 same as the one used to pre-populate the cache.

 I was also surprised (though less so) at the opposite, that *not*
 including the non-default DB (on line 64) *was* able to hit the cache
 (which was populated by "replica") instead of hitting the default database
 (as the query would normally do).

 On IRC chatting about this, the question was: "Well, should filter hit the
 DB or use the cache? What about exclude and other methods? Where do you
 draw the line?" I think the simple line to draw is whether something
 changes the SQL query. using() methods don't change SQL, so they should
 work properly on a cached result. filter() and exclude() do change the
 SQL, so they *shouldn't* use the cache.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30079>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/051.56ad9d27482adcbf7542976b9f3c028f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to