Earlier quoted context omitted.
Would GraphQL be a good starting point for such a language?
It was sarcasm, he was referring to SQL lol
Ban 1+N in Django
101–110 of 153 posts
Re: Ban 1+N in Django
#102Re: Ban 1+N in Django
#103Rails has Bullet[0] to help identify and warn you against N+1 Does Django have anything active? Quick search revealed nplusone[1] but its been dead since 2018. [0] https://github.com/flyerhzm/bullet [1] https://github.com/jmcarp/nplusone
There is django-zen-queries[0], mentioned in another comment. [0] https://github.com/dabapps/django-zen-queries
Re: Ban 1+N in Django
#104I wonder why ORMs still(?) work as simple wrappers and never track access patterns. If you see that `in books` generator’s results experience accesses through a relationship, it’s pretty obvious to join it in advance after few misses and serve `book.author.full_name` from cache. Of course that would make ORM more complex, but why would you need one otherwise. A good database interface should make good guesses, probab…
I don't want my app to change performance-sensitive behavior at runtime, that's a debugging nightmare. I do want my framework to throw an error in development mode if I screw up the preloading.
Re: Ban 1+N in Django
#105I wonder why ORMs still(?) work as simple wrappers and never track access patterns. If you see that `in books` generator’s results experience accesses through a relationship, it’s pretty obvious to join it in advance after few misses and serve `book.author.full_name` from cache. Of course that would make ORM more complex, but why would you need one otherwise. A good database interface should make good guesses, probab…
I dont know any of this but doesn't the OP give a solution similar to this https://github.com/Suor/django-cacheops
Re: Ban 1+N in Django
#106I wonder why ORMs still(?) work as simple wrappers and never track access patterns. If you see that `in books` generator’s results experience accesses through a relationship, it’s pretty obvious to join it in advance after few misses and serve `book.author.full_name` from cache. Of course that would make ORM more complex, but why would you need one otherwise. A good database interface should make good guesses, probab…
I dont know any of this but doesn't the OP give a solution similar to this https://github.com/Suor/django-cacheops
Re: Ban 1+N in Django
#107Earlier quoted context omitted.
There is django-zen-queries[0], mentioned in another comment. [0] https://github.com/dabapps/django-zen-queries
Not a fan of this one since it only works on templates and requires special code
Regarding extra code, you can simply replace the Djangos' `render()`, with the one from this lib and you are done. I would have probably made a custom template extension or something to do that for all renders automatically though too.
Re: Ban 1+N in Django
#108Earlier quoted context omitted.
So, in other words, you want GraphQL.
A dataloader sort of pattern tends to be on the implementing end of GraphQL.
However, a dataloader pattern can also be useful when implementing custom resolvers for a GraphQL API. For this purpose, Apollo provides data sources which handle caching at request level.
Re: Ban 1+N in Django
#109Re: Ban 1+N in Django
#110There is a case where having N+1 queries are beneficial. In Rails terms, it's when you perform Russian doll caching, but you can do this in any framework. The idea is you can cache a specific X thing which might make a query to an associated Y thing. A textbook N+1 query case (ie. a list of posts (X) that get the author's name (Y)). If you render the view without any cache with 10 things then you'd perform 20 queries…
> If you render the view without any cache with 10 things then you'd perform 20 queries but after the cache is warm you'd perform 0 queries. If item 5's Y gets updated then you only need to bust the cache for item 5 and query only item 5's Y association. Performing a preloaded query to get all X 10 things with their Y associated things could be an expensive query.
So instead of "do one query to the database, zero if cache is hot, one query again if you invalidate it", you do 20 queries, zero if cache is hot (but 20 cache queries), then 1 if you invalidate it.
That's nice method when single entry query is very expensive but in most cases it will be living in DB cache already.
It is only a win if DB is the bottleneck which by far is rarer case nowadays than RTT. Also you could just query all 20 records at once but write it to cache as separate records, then have write-thru logic for updating records. Best of both at cost of some complexity.
You can also just... cache the resulting page instead of data-level caching, and not engage app code in most requests in the first place. Partial caching with ESI is also possible although pretty involved.