|
|
|
|
|
by globular-toast
505 days ago
|
|
The main problem is if you are not very careful it leaks its internals (ie. the relational model) into everything it touches. That's what the N+1 query problem is. Business logic shouldn't have to know that certain attributes will cause database queries. By carefully writing managers and having a rule to never use querysets anywhere else you can avoid it, but it requires everyone to understand this and all the Django docs and examples everywhere will just randomly drop a queryset into a view or do a `prefetch_related` because they know that some higher-level function is going to need access to that attribute (ie. coupling code together). Ultimately Django just doesn't fully do the object-relational mapping. It maps single rows, but that's it. So it doesn't really support objects that contain lists or sets etc. Things like SQLAlchemy can actually map data from a relational database into plain old objects. Those objects can be instantiated (e.g. in tests) completely independently of the database. Notice how in Django you can't test anything without a database being present? Why do I need to store an object in a db just to test some method on an entity? |
|
I really don't get these arguments because in some form or another, ALL abstractions are leaky.
Example:
A novice developer might write a @OneToMany in hibernate without knowing the internals of the abstraction, causing n+1 problems. Two paths forward:
1. blame the abstraction
2. Learn (some) internals of the abstraction in order to use it correctly: dont do eager fetching, use join fetches, ... ( There's also tooling like hypersistence optimizer, digma, jpabuddy that comes to mind)
And by that same logic, would you berate somebody writing 'plain SQL' which - when expected with the query plan - turns out to be a very unperformant query?
Again, two options:
1. blame the abstraction
2. Learn (some) internals of the abstraction: analyze the query plan, perhaps write some indexes,...