logoalt Hacker News

red_admiralyesterday at 4:48 PM7 repliesview on HN

This is what you get when you let your ORM loose on the database without understanding JOINs. Especially, the bit where something like 'book.author.name' that looks like a simple field dereference actually is a method call on an ORM proxy object (book), via python's __getattr__ or similar, that fires off a new query if the data you want is not loaded yet.

Some ORMs let you specify the extent of the data that you want, like Hibernate has its own Hibernate Query Language.

At some point you are better off just writing SQL yourself, though. Even without join problems, if you ask an ORM to get the person with user id 123 and all you want is their name, the ORM cannot know that unless to tell it, and so you end up with a 'SELECT *' type query.


Replies

BeetleByesterday at 8:16 PM

Dealing with Django, they give quite a few ways to query data. For the small internal web site we ran, I've yet to encounter an N+1 situation that I didn't find an alternative Django API that I should have been using.

Not saying you never need bare SQL on Django sites, but the Django ORM does have some sophisticated APIs to prevent this problem.

> Even without join problems, if you ask an ORM to get the person with user id 123 and all you want is their name, the ORM cannot know that unless to tell it

So ... tell it! You can specify in a query to fetch only certain data, and not the whole object.

plaguuuuuuyesterday at 8:29 PM

People always say this and my experience in C# has been the opposite. I've never wanted to reach for raw SQL and hardly ever do, only if its because there's no extension to do SKIP..LOCKED or something

var name = dbContext.Users .Where(u => u.Id == 123) .Select(u => u.Name) .First();

show 1 reply
stephenyesterday at 10:50 PM

> all you want is their name

I have a WIP PR that addresses exactly this:

https://github.com/joist-orm/joist-orm/pull/1967

cnityyesterday at 5:01 PM

ORMs are great. They make the easy queries remain easy and the harder queries impossible.

tehlikeyesterday at 5:19 PM

This is true but not super true in case of linq and related providers like efcore. Even nhibernate linq would do this.

seki285yesterday at 6:42 PM

You should write a raw SQL query to grab just a user's name only when there's a need for that.

ddorian43yesterday at 7:22 PM

Or set lazy loadin to "raise" in the relationships and get exceptions if you dont explicitly join.