Hacker News new | ask | show | jobs
by ram_rar 306 days ago
Unpopular opinion: in 2025, nobody should be reaching for an ORM first. They’re an anti-pattern at this point. The “abstraction” it promises rarely delivers—what you actually get is leaky, slow, and a nightmare to operate at scale.

The sane middle ground is libraries that give you nicer ergonomics around SQL without hiding it (like Golangs sqlx https://github.com/jmoiron/sqlx). Engineers should be writing SQL, period.

5 comments

I think you're fundamentally misunderstanding the primary purpose of an ORM. It's in the name - Object Relational Mapper. It's meant to ease the mapping from SQL query results into objects in your code, and from objects back to SQL queries. Doing this manually at scale when you have a large number of tables is also a nightmare.

There's no rule saying you can't integrate your own manually written SQL with an ORM, and in fact, any production-ready, feature-complete ORM will allow you do it, because it's effectively a requirement for any non-trivial use case.

Well said. Please never be silent over this fact. It's important to educate people on what an ORM is, what it means and especially what it doesn't mean. Especially in times where VC-baked companies misinform and manipulate people about that, like Prisma is doing
the trouble is that even if people embrace that thinking, the ORM encourages them to pull entities out of the db and do a bunch of computation in the server that would be much faster to do in the db.
Strongly agree! Rust’s sqlx is also insanely great, and I like sqlc for Go as well.

I’ve written a lot about this particular topic: https://www.jacobelder.com/2025/01/31/where-shift-left-fails...

> Engineers should be writing SQL, period.

As another commenter wrote:

”If you're doing OLAP…SQL isn't wholly adequate for this, it's hard work to get the SQL right and if there's joins involved it's not hard to accidentally fan out and start double counting.”

I feel this in my bones. Anytime someone in the business changes something in a source system, the joins create extra rows. Trying to address this with SQL is like plowing a field with a spoon.

And I don’t think ORMs are the answer. Just imperative code. The ability to throw in a few lines of sanity checking outside of SQL is such a massive boost to reliability and data quality, when the source systems are moving underneath your feet.

In my experience, LATERAL is a massive quality-of-life improvement when it comes to double-counting specifically; where a normal subquery is not possible, a correlated subquery in FROM is much nicer than a CTE+JOIN.

Doubleagree on sanity checks.

> The sane middle ground is libraries that give you nicer ergonomics around SQL without hiding it (like Golangs sqlx https://github.com/jmoiron/sqlx). Engineers should be writing SQL, period.

The blog suggests that an ORM for OLAP would do exactly that

> Engineers should be writing SQL, period.

Is it a variation of: "I suffered when I was young, so everyone must suffer as I did?"

SQL is terrible, however you slice it. It's a verbose bass-ackwards language. ORMs that remove the need to deal with SQL for 99% of trivial cases are great.

The rest 1% can remain painful.

Please stop spewing nonsense.

SQL remains the only way to efficiently perform MANY computations in the database precisely because it's lingua franca for the database planner. If you're not writing SQL, it doesn't mean that you're unable to cover 1% of the queries, it only means that you're leaving 99% of performance on the table. You can tell a bad programmer by their refusing to use views and materialized views. Not to mention normalisation! I'm yet to see a coder using ORM produce a sane schema. And don't get me started on aggregates. Relational databases represent relations, not objects, period.

Please stop spewing nonsense.

> If you're not writing SQL, it doesn't mean that you're unable to cover 1% of the queries, it only means that you're leaving 99% of performance on the table.

Honestly? You're spewing bullshit. In most apps most of SQL is trivial. It's typically limited to simple joins (with indexes) with simple filters. Anything more complicated, and it's usually not suitable for OLTP. Heck, all our SQL is linted to not have full-table scans.

This kind of SQL is perfectly auto-generated by ORMs.

Those multi-page queries that required mystic DB knowledge for placing hints, burning incense, and paying $1000 per hour to Oracle consultants? They're entirely useless in modern software stacks. Because you can either keep the entire working set in RAM so these queries can be trivially rewritten, or you just won't use regular SQL for it.

> You can tell a bad programmer by their refusing to use views and materialized views.

You can tell a bad programmer by them using DB in a way that requires materialized views. It typically ends with moving app logic into SQL, and may even lead to "SELECT '<td>' + row.cust_name + '</td>'".