I have the following unit test:
def test_cache(self):
with self.assertNumQueries(1):
print(database.records.all())
print(database.records.all())
print(database.records.all())
The test fails because 3 queries are made:
Captured queries were:
1. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
2. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
3. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
Why is the records field not cached? What is telling Django to do refetch the data from the database?
As documented :
As well as caching of the whole QuerySet, there is caching of the result of attributes on ORM objects. In general, attributes that are not callable will be cached. For example, assuming the example blog models:
entry = Entry.objects.get(id=1) entry.blog # Blog object is retrieved at this point entry.blog # cached version, no DB access But in general, callable attributes cause DB lookups every time: entry = Entry.objects.get(id=1) entry.authors.all() # query performed entry.authors.all() # query performed again
But this is not problem as if you need to access authors ( store_records in your case) you would properly use prefetch_related