﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
30079	Prefetch cache should be aware of database source and .using() should not always trigger a new query	Mike Lissner	nobody	"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. "	Cleanup/optimization	closed	Documentation	dev	Normal	wontfix	prefetch, multidatabase		Unreviewed	1	0	0	0	0	0
