Live data from Hacker News

Ban 1+N in Django

suor.github.io

91–100 of 153 posts

Re: Ban 1+N in Django

#92
post #13

Earlier quoted context omitted.

You'd ideally want to do something like dataloader, where you look up your N Xs in a single cache query, and then do a single database lookup for the (N-C) Xs that weren't in cache. You can then either eagerly load the Ys with the Xs like you said, or do a secondary cache lookup for every Y, and potentially another single database query for the Ys not in cache. Unfortunately this pattern gets really hairy if you're n…

So, in other words, you want GraphQL.

A dataloader sort of pattern tends to be on the implementing end of GraphQL.

Re: Ban 1+N in Django

#93

Earlier quoted context omitted.

The ORM provides a myriad other features, like adapters for every production database under the sun, query composition that is literally impossible in plain SQL, a reasonable interface to the admin and the ecosystem of Django apps, and above all: a logical interface that maps _business objects_ to their SQL tables. The ORM hate seems to come from people whose day to day interaction with data tables isn't mediated by…

... Or by people that actually understand the impedance mismatch between objects and data (quick django example - request data and models are different and not easily interchangeable). Or people that require good caching implementations. Or people that actually design database systems schema-first. Or peoplw that rely on advanced usage that isnt always easy to perform in orm's. The list goes on.

Django's ORM is much better than most, to the point where Django considers that "I can't model this query with the ORM" to be a bug.

There are of course some mismatches, but it's pretty hard to have a query that is not at all modelable, and Django's ORM is ... fairly predictable (I have some gripes about how obvious or not joins are but it's subjective).

Re: Ban 1+N in Django

#94
post #83

sentry.io is pretty good at catching N+1 queries.

Sentry has a lot of GDPR problems, it's not easy to set it up so you don't leak PII in e.g. traces sent to it.

You can self-host the open-source version, it's dockerized and pretty easy to set up...

Re: Ban 1+N in Django

#95

Rails 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

If I understand it correctly, that's what [django-seal](https://github.com/charettes/django-seal) does.

Re: Ban 1+N in Django

#96
post #36

This is why I always advocated against ORMs. It’s so easy to fall into traps like this without even knowing it, and while you can work around it in some ORMs it is not obvious. Writing SQL is not that hard, and mapping the results to a type isn’t that hard either. So with an ORM you might end up saving several hours of work up front for lots of pain later.

> Writing SQL is not that hard, and mapping the results to a type isn’t that hard either. But... Then you've written an ORM.

So many people say this, but I have to imagine that such people haven't actually really tried to write SQL in their services and avoid the temptation to introduce all sorts of abstractions.

Because in my experience this doesn't happen. You just have to be OK with some duplication (which most engineers over-focus on to the point of serious detriment).

Re: Ban 1+N in Django

#97
If only there were some way to retrieve information from disparate tables in a single request. Almost like some way to "join" the tables together... you could design a simple declarative language specific for querying in such a way. A "query language" if you will. It would have a simple structure, a structured query language, that enables you to get this data in a performant way without making N requests!

I might go and make this.

Re: Ban 1+N in Django

#98
post #97

If only there were some way to retrieve information from disparate tables in a single request. Almost like some way to "join" the tables together... you could design a simple declarative language specific for querying in such a way. A "query language" if you will. It would have a simple structure, a structured query language, that enables you to get this data in a performant way without making N requests! I might go…

Would GraphQL be a good starting point for such a language?

Re: Ban 1+N in Django

#99
post #97

If only there were some way to retrieve information from disparate tables in a single request. Almost like some way to "join" the tables together... you could design a simple declarative language specific for querying in such a way. A "query language" if you will. It would have a simple structure, a structured query language, that enables you to get this data in a performant way without making N requests! I might go…

Would GraphQL be a good starting point for such a language?

It was sarcasm, he was referring to SQL lol

Re: Ban 1+N in Django

#100
post #9

I don't disagree with the author in principle, but I find once the data gets big enough where it makes a difference, I've already shifted to using ".values()" to avoid the overhead of model creation, and the KeyErrors that will throw if I leave the query lazy is tantamount to the solution he describes.

Same, and using raw queries too when needed. Identify hot spots and do those. Regular ORM is fine for the rest (mostly).
Post reply on HN