Readit News logoReadit News
superasn · a month ago
Always use ORMs and then spend the next year debugging N+1 queries, bloated joins, and mysterious performance issues that only show up in prod.

Migrations randomly fail, schema changes are a nightmare, and your team forgets how SQL works.

ORMs promise to abstract the database but end up being just another layer you have to fight when things go wrong.

skinkestek · a month ago
People love to rant about ORMs.

But as someone who writes both raw SQL and uses ORMs regularly, I treat a business project that doesn’t use an ORM as a bit of a red flag.

Here’s what I often see in those setups (sometimes just one or two, but usually at least one):

- SQL queries strung together with user-controllable variables — wide open to SQL injection. (Not even surprised anymore when form fields go straight into the query.)

- No clear separation of concerns — data access logic scattered everywhere like confetti.

- Some homegrown “SQL helper” that saves you from writing SELECT *, but now makes it a puzzle to reconstruct a basic query in a database

- Bonus points if the half-baked data access layer is buried under layers of “magic” and is next to impossible to find.

In short: I’m not anti-SQL, but I am vary of people who think they need hand-write everything in every application including small ones with a 5 - 50 simultaneous users.

kaptainscarlet · a month ago
People who avoid ORMs endup writing their own worse ORM*. ORMs are perfect if you know how and when to uses them. They encapsulate a lot of the mind numbing work that comes with raw sql such as writing inserts for a 50 column database.
tetha · a month ago
I'd say, pure SQL gives you a higher performance ceiling and a lower performance and security floor. It's one of these features / design decisions that require diligence and discipline to use well. Which usually does not scale well beyond small team sizes.

Personally, from the database-ops side, I know how to read quite a few ORMs by now and what queries they result in. I'd rather point out a missing annotation in some Spring Data Repository or suggest a better access pattern (because I've seen a lot of those, and how those are fixed) than dig through what you describe.

sjducb · a month ago
100%

If a dev thinks that all SQL can be written by hand then they probably haven’t worked with a complex application that relies on complex data.

A good question to ask them is: what problems do ORMs solve? Good answers are:

Schema Changes + migration

Security

Code Traceability (I have a DB field, where is it used)

Code Readability

Standardisation - easy hiring.

Separation of data layer logic and application layer logic.

Code organisation, most ORMs make you put methods that act on a table in a sensible place.

phendrenad2 · a month ago
I think people should go all-in on either SQL or ORMs. The problems you described usually stem from people who come from the ORM world trying to write SQL, and invariably introducing SQL injection vulnerabilities because the ORM normally shields them from these risks. Or they end up trying to write their own pseudo-ORM in some misguided search for "clean code" and "DRY" but it leads to homegrown magic that's flaky.
sam_lowry_ · a month ago
In Java, the sweet spot is JDBCTemplate. Projects based on JDBCTemplate succeed effortlessly while teams muddle through JPA projects.

It is not that JPA is inherently bad, it's just that such projects lack strong technical leadership.

CafeRacer · a month ago
Sir, sqlc for example.

I know exactly what's going on, while getting some level of idiocy protection (talking about wrong column names, etc).

DanHulton · a month ago
Poor developers use tools poorly, film at 11.

But seriously, yeah, every time I see a complaint about ORMs, I have to wonder if they ever wrote code on an "average team" that had some poor developers on it that didn't use ORMs. The problems, as you describe them, inevitably are worse.

j45 · a month ago
ORMs can be the starting point to optimize the queries when they need it manually with SQL.

There's also the reality that no two ORMs may be built to the same way and performance standard.

strken · a month ago
I'm wary of people who are against query builders in addition to ORMs. I don't think it's possible to build complicated search (multiple joins, searching by aggregates, chaining conditions together) without a query builder of some sort, whether it's homegrown or imported. Better to pull in a tool when it's needed than to leave your junior devs blindly mashing SQL together by hand.

On the other hand, I agree that mapping SQL results to instances of shared models is not always desirable. Why do you need to load a whole user object when you want to display someone's initials and/or profile picture? And if you're not loading the whole thing, then why should this limited data be an instance of a class with methods that let you send a password reset email or request a GDPR deletion?

sherburt3 · a month ago
At least when I see raw sql I know me and the author are on a level playing field. I would rather deal with a directory full of sql statement that get run than some mysterious build tool that generates sql on the fly and thinks its smarter than me.

For example, I'm working on a project right now where I have to do a database migration. The project uses c# entity framework, I made a migration to create a table, realized I forgot a column, deleted the table and tried to start from scratch. For whatever reason, entity framework refuses to let go of the memory of the original table and will create migrations to restore the original table. I hate this so much.

edem · a month ago
all of this is solved by an sql query builder DSL
nsksl · a month ago
> - Some homegrown “SQL helper” that saves you from writing SELECT *, but now makes it a puzzle to reconstruct a basic query in a database

>- Bonus points if the half-baked data access layer is buried under layers of “magic” and is next to impossible to find.

It’s really funny because you’re describing an ORM perfectly.

Dead Comment

PaulHoule · a month ago
You really want something that lets you write

  table=db.table("table1")
  table.insert({"col1": val1, "col2": val2})
at the very least, if you are really writing lots of INSERTs by hand I bet you are either not quoting properly or you are writing queries with 15 placeholders and someday you'll put one in the wrong place.

ORMs and related toolkits have come a long way since they were called the "Vietnam of Computer Science". I am a big fan of JooQ in Java

https://www.jooq.org/

and SQLAlchemy in Python

https://www.sqlalchemy.org/

Note both of these support both an object <-> SQL mapper (usually with generated objects) that covers the case of my code sample above, and a DSL for SQL inside the host language which is delightful if you want to do code generation to make query builders and stuff like that. I work on a very complex search interface which builds out joins, subqueries, recursive CTEs, you name it, and the code is pretty easy to maintain.

Scarblac · a month ago
I always see this sentiment here but I just havent experienced any of it in 14 years with the Django ORM.
sethammons · a month ago
My life is this in django. Querysets have been passed around everywhere and we've grown to 50 teams. Now, faced with ever slower dev velocity due to intertwined logic, and reduced system performance with often wildly non performant data access patterns, we have spent two years trying to untangle our knot of data access, leading to a six month push requiring disruption to 80% of team's roadmaps to refactor to get the ORM objects not passed around, but to use plain types or DTOs, which will only then allow us to migrate a core part of our database which is required for both product development and scaling needs.

Here's the thing. In five of six companies I have worked at, this story is the exact same. Python, Ruby, Elixir. Passing around ORM objects and getting boundaries mixed leading to more interdependencies and slower velocities and poor performance until a huge push is required to fix it all.

Querysets within a domain seems fine, but when you grow, domains get redefined. Defining good boundaries is important. And requires effort to maintain.

rahimnathwani · a month ago
You've never had to use

  .extra()

?

ormsaregreat · a month ago
Hitting the database should be avoided in a web application, and use keys as much as possible. All heavy objects should be previously cached in disk.
kiliancs · a month ago
I like Ecto's approach in Elixir. Bring SQL to the language to handle security, and then build opt-in solutions to real problems in app-land like schema structs and changesets. Underneath, everything is simple (e.g. queries are structs, remain composable), and at the driver layer it taks full advantage of the BEAM.

It's hard to find similarly mature and complete solutions. In the JS/TS world, I like where Drizzle is going, but there is an unavoidable baseline complexity level from the runtime and the type system (not to criticize type systems, but TS was not initially built with this level of sophistication in mind, and it shows in complexity, even if it is capable).

OkayPhysicist · a month ago
Ecto is a gold-standard ORM, in no small part because it doesn't eat your database, nor your codebase. It lives right at the intersection, and does it's job well.
Tade0 · a month ago
A couple of years ago I had an opportunity to fill a fullstack role for the first time in several years.

First thing I noticed was that I couldn't roll an SQL statement by hand even though I had a distinct memory of being able to do so in the past.

I went with an ORM and eventually regretted it because it caused insurmountable performance issues.

And that, to me, is the definition of a senior engineer: someone who realised that they've already forgotten some things and that their pool of knowledge is limited.

mattmanser · a month ago
ORMs are absolutely fantastic at getting rid of the need for CRUD queries and then boilerplate code for translating a result set to a POCO and vide versa. They also allow you to essentially have a strongly typed database definition. It allows you to trivialise db migrations and versioning, though you must learn the idiosyncrasies.

What they are not for is crafting high performance query code.

It literally cannot result in insurmountable performance issues if you use it for CRUD. It's impossible because the resulting SQL is virtually identical to what you'd write natively.

If you try to create complex queries with ORMs then yes, you're in for a world of hurt and only have yourself to blame.

I don't really understand people who still write basic INSERT statements. To me, it's a complete waste of time and money. And why would you write such basic, fiddly, code yourself? It's a nightmare to maintain that sort of code too whenever you add more properties.

ethbr1 · a month ago
My definition of a senior engineer is someone who can think of most of the ways to do a thing... and has the wisdom to chose the best one, given the specific situation’s constraints.
listenallyall · a month ago
Perhaps because databases were fundamental to the first programs I ever built (in the ancient 19xx's), but damn, I cannot believe how many so-called experienced devs - often with big titles and bigger salaries - cannot write SQL. It's honestly quite shocking to me. No offense, but wow.
vimto · a month ago
This is a common sentiment because so many people use ORMs, and because people are using them so often they take the upsides for granted and emphasise the negatives.

I've worked with devs who hated on ORMs for performance issues and opted for custom queries that in time became just as much a maintenance and performance burden as the ORM code they replaced. My suspicion is the issues, like with most tools, are a case of devs not taking the time to understand the limits and inner workings of what they're using.

npteljes · a month ago
This fully matches my experience, and my conclusions as well. I'd add that I often don't get to pick whether the logic will be more on the ORM side, or on the DB side. I end up not caring either - just pick a side. Either the DB be dumb and the code be smart, or the other way around. I don't like it when both are trying to be smart - that's just extra work, and usually one of them fighting the other.
CafeRacer · a month ago
The reason why I dislike ORMs is that you always have to learn a custom DSL and live in documentation to remember stuff. I think AI has more context than my brain.

Sql does not really needs fixing. And something like sqlc provides a good middle ground between orms and pure sql.

cluckindan · a month ago
There is a solution engineered specifically for avoiding N+1 queries and overfetching: GraphQL.

More specifically a GraphQL-native columnar database such as Dgraph, which can leverage the query to optimize fetching and joining.

Or, you could simply use a CRUD model 1:1 with your database schema and optimize top-level resolvers yourself where actually needed.

Prisma can also work, but is more susceptible to N+1 if the db adapter layer does separate queries instead of joining.

jjice · a month ago
Prisma has shown me that anything is possible with an ORM. I think they may have changed this now, but at least within the last year, distincts were done IN MEMORY.

They had a reason, an I'm sure it had some merit, but we found this out while tracking down an OOM. On the bright side, my co worker and I got a good joke to bring up on occasion out of it.

amonith · a month ago
That sounds plausible in theory, but I've been developing big ol' LOB apps for more than 10 years now and it happens very very sporadically. I mean bloated joins is maybe the most common, but never near enough bloated to be an actual problem.

And schema changes and migrations? With ORMs those are a breeze, what are you're on about. It's like 80% of the reason why we want to use ORMs. A data type change or a typo would be immediately caught during compilation making refactoring super easy. It's like a free test of all queries in the entire system. I assume that we're talking about decent ORMs where schema is also managed in code and a statically typed language, otherwise what's the point.

We're on .NET 8+ and using EF Core.

DangitBobby · a month ago
ORM hate might as well be a free square on "HN web development blog post Bingo".
tossandthrow · a month ago
Funny, I use prisma and pothos, with p99 at below 50ms - no N+1

(when it is not lower, then it is because there are sec framework and other fields that might not be mapped directly do the prisma schema)

porridgeraisin · a month ago
Doesn't prisma do many sql features like distinct... In memory?
at-fates-hands · a month ago
Just in case:

Object-relational mapping (ORM) is a key concept in the field of Database Management Systems (DBMS), addressing the bridge between the object-oriented programming approach and relational databases. ORM is critical in data interaction simplification, code optimization, and smooth blending of applications and databases. The purpose of this article is to explain ORM, covering its basic principles, benefits, and importance in modern software development.

avgDev · a month ago
Why can't one use ORM and then flag queries which are slow? This is trivial.

Inspect the actual SQL query generated, and if needed modify ORM code or write a SQL query from scratch.

tonyhart7 · a month ago
we have AI that scans for any potential query N+1 right now

people forget how sql works??? people literally try to forget on how to program

more and more programmer use markdown to "write" code

sandeepkd · a month ago
At the end of day its a trade off. It would be an exception if anyone can remember their own code/customization after 3 months. ORMs or frameworks are more or less conventions which are easier to remember cause you iterate on them multiple times. They are bloated for a good reason, to be able to server much larger population than specific use cases and yes that does brings its own problems.
lmm · a month ago
Weeks of handwriting SQL queries can save you hours of profiling and adding query hints.

If you want a maintainable system enforce that everything goes through the ORM. Migrations autogenerated from the ORM classes - have a check that the ORM representation and the deployed schema are in sync as part of your build. Block direct SQL access methods in your linter. Do that and maintainability is a breeze.

benoau · a month ago
The only time I've seen migrations randomly fail was when others were manually-creating views that prevented modifications to tables. Using the migrations yourself for local dev environments is a good mitigation, except for that.
martin82 · a month ago
Skill issue.

In the hand of a good team, ORMs and migrations are an unbeatable productivity boost.

Django is best in class.

ormsaregreat · a month ago
Pro tip. Don't use Django migrations. Manage the database first and mirror it in orm later.
rick1290 · a month ago
Why? Isn't this easier to screw up the prod db?
Too · a month ago
Business opportunity: Invent a type system that prevents N+1 queries.
FridgeSeal · a month ago
But think of how much time you’ll save needing to map entities to tables!!!! Better to reinvest that time trying to make the ORM do a worse job, automatically instead!!
mdavid626 · a month ago
Or just use MongoDB. No ORM needed.
skinkestek · a month ago
Very practical, like a credit card.

Let's you do what you want here and now and then pay dearly for it afterwards :-)

pjc50 · a month ago
Eh, nobody wants to transfer rows to DTOs by hand.

My personal opinion is that ORMs are absolutely fine for read provided you periodically check query performance, which you need to do anyway. For write it's a lot murkier.

It helps that EF+LINQ works so very well for me. You can even write something very close to SQL directly in C#, but I prefer the function syntax.

pier25 · a month ago
Yeah EF is amazing
rckt · a month ago
The post feels more like a rant, like the author has a beef with some sort of a project or a client. Even a static blog is easier to manage with tools rather than writing it in pure HTML.

I have my personal website running on svelte. When I decided to have a blog, I quickly came up with a solution to use markdown to html converter and just added a couple of routes to existing setup and voila, the blog is up and running. I don't care that it depends on several packages. Publishing a post takes just a push to my repo.

austin-cheney · a month ago
No it doesn’t. This post reads like someone tired of working in an industry run by extremely insecure people that just need a little help at absolutely every step of the journey. Other industries call that unqualified.
cdaringe · 22 days ago
Seems like you’re projecting, to me.
socalgal2 · a month ago
I have a personal web app that I wrote in react 16 with babel set up by createReactApp directly from the react docs. it’s been stuck with a list of features I want to add in my spare time but all 3 of those have bitrotted out so that in my minor spare time over the last 2 years or so, instead of being able to add some feature, I spend 2 to 3 hours trying to update it to the latest, fail, and no progress is made.

my latest attempt was to see if one of the LLMs could do it. nope.

I’ve thought about starting from scratch but don’t have the time

rckt · a month ago
Yeah. The frontend world is a mess. I also faced similar issue with my personal website. Now I just keep my packages versions up to date and do any breaking changes updates as soon as possible. It's annoying, but it's better this way than having to re-write/refactor the whole thing every time.
DecoySalamander · a month ago
I think you will have a much better time if you generate a new, empty React project with Vite and just drop your existing components into it. I almost suggested not updating at all and keeping your dependencies as they are, but createReactApp was too much of a bloated mess even in its heyday.
1dom · a month ago
You're clearly a better person than the author then.

They said at the start they were going on personal experience. I relate deeply to what they're saying: it's most definitely not a rant/beef against another project/client, it's most definitely the learnings of someone who's been producing personal websites for decades, has kicked themselves a few times in the process and can sarcastically poke fun at their journey in front of others.

judge123 · a month ago
The problem isn't the tool or the dependency—it's the developer's temptation to over-engineer. We grab a framework because we lack the discipline to keep something simple. Is self-control in coding just a lost art now?
Cthulhu_ · a month ago
> Is self-control in coding just a lost art now?

Yes; a lot of people don't code because they need to make something work, they code for the joy of it. When the software they need to write is boring or solved - like another CRUD app, front- or back-end - instead of picking the boring and easy to build and comprehend languages and frameworks, they will make it interesting for themselves. Learn a new language, framework, or design paradigm; follow whatever is trending at the moment, etc.

A lot of new software is over-engineered from the start. A lot of that is cargo cult as well, e.g. big companies use microservices in their custom k8s cluster, therefore we should use microservices in our custom k8s cluster too.

dotancohen · a month ago

  > they will make it interesting for themselves.
Engineers love to solve problems. If there are no problems readily at hand, they will create some.

lmpdev · a month ago
Also the inverse though

Things like Wordpress sound super simple - you don’t even need to code!

But you do need to worry about managing an entire Apache server, managing a crappy database, hardcoding bullshit in PHP, cronjobs, cloud deployment and the fact that almost all “features” of it like plugins and themes etc are massive security vulnerabilities

I think the pitfall to avoid ITT is that there’s a single source of maintenance effort - there are likely many!

rglullis · a month ago
If the problem you are trying to solve is "I need to put content online and have a storefront for my product", there are plenty of hosting providers who will happily take care of all the headache from Wordpress for less than $10/month.
kunley · a month ago
Certain tools, or rather: ecosystems encourage overengineering and overhyping more than others.
mettamage · a month ago
> We grab a framework because we lack the discipline to keep something simple.

I grab a framework to also keep my skills relevant, especially if I'm not practicing them in my day job. If I didn't have that impulse, I'd keep it simple all the time. I'm really good at it, because I really dislike complexity as it requires me to remember more things and I don't really like that feeling.

I'll optimize if I absolutely have to.

Not that businesses ever cared about this attitude. I mean, I've seen it work. The work that I do with LLMs is quick and pragmatic. No need to put stuff into production when it's just a prototype. No need to use a framework if gluing an LLM with some Python code and a well crafted prompt produces the result we need. It allows me to ship in days, not weeks. Obviously, if one then wants it productionized, additional work needs to be put into it and possibly the code needs to be refactored. But, in my opinion, that's the time and place where that type of stuff should happen.

whstl · a month ago
I have never seen this as the justification for using a framework.

As a rationalization, sure, but never as the reason.

They do offer more than coding standards.

djeastm · a month ago
For me it's more like I bounce back and forth avoiding the pains from whatever the last project was using. Same with front-end frameworks vs vanilla JS etc.

For example, you work with ORMs and then you see all the problems with them as you maintain the project, so on your next app you create an app that is raw SQL. Then after maintaining that for awhile you start to see all the pitfalls of that approach and why people created ORMs in the first place. Then someone mentions the latest and greatest ORM that promises to be better this time and you use it, saving you from raw SQL you'd jumped to last time....ad infinitum.

ThatMedicIsASpy · a month ago
I make choices one of that is build a website in php. I do things from scratch so it involved learning the server, the setup (security/docker/podman), the stack (php/js/css/html). My limits made me do things. The code was and is ugly. Everything is a mess. There is no routing my URLs are pretty because of nginx rewrites. My limits make design choices like no user data because I cannot be sure about security. Once it is up and running you look at things like bootstrap to learn basics of css. Then you want it all gone because you learned the way of css.

I have no problem with sql but an ORM makes what I know about sql very ugly.

atoav · a month ago
Not for me. But I am in the unique situation of sometimes having to spin up 12 projects a week only to come back to two of them 5 weeks later unpredictably.

This means I treat every project like a letter to my future self that needs to be 100% self explainatory and work even if the environment around the project changed. And this means as few moving parts as possible.

joks · a month ago
Sometimes it's just more fun to over-engineer things.
johnisgood · a month ago
I intentionally avoided using a framework mainly to keep my code simple, and because the framework was too inflexible and I could not achieve what I wanted to.
cpursley · a month ago
So you then ended up building your own half baked of a … wait for it … framework, without even realizing it. Nothing wrong with that, it can be fun - just depends on if your goals are shipping or playing around.
MOARDONGZPLZ · a month ago
This seems to me to be exactly what the post is about.
donatj · a month ago
I always get a kick out of the posts from the people in language communities who post "I'm new to <language>, what framework should I use?"

It's like asking "I'm new to driving, what brand of nitros should I be using"

Nah dude, get your sea legs first

Towaway69 · a month ago
Depends on the context. I came from a ruby, nodejs, java, gawk background to Erlang (not elixir).

The first question I posed to the Erlang community was exactly that: what are the build tools, what are the unit testing frameworks and how is a project setup.

Not because I didn’t know what these tool/concepts did but because I wanted to know what is the state of the art in Erlang tooling.

I have my sea legs, including the wooden one, but just not yet in Erlang. Why Erlang? Because it’s completely different to everything else!

LanceH · a month ago
Depends on the language. This one is pretty settled in Ruby.
fifticon · a month ago
I have a good one(?):

1. be multiple developers on the same project.

2. for each developer, use your own tools and techniques, insist on only handling those parts of the site that you did with your tools, and insist on never fully understanding those remaining parts of the site the other devs did.

This will allow for all sorts of fun, including:

- A multiple inconsistent implementations of the same thing

- B even better, those multiple inconsistent implementations affecting and breaking each other!

One you have this going, there are some easy bonus pickings: Whenever B happens, "fix" it with weird extra incancations inside your own toolset, cleverly avoiding any attempt at (2) above.

If you succeed at this, several developers can, combining these techniques to sabotage and trigger a veritable pinball game of strange breaking effects.

Note: CSS is a great place to start this game!

anonzzzies · a month ago
1. do all devops on the side and make sure everything is running complex multi az kubernetes clusters with as many aws buzzword services you managed to read when you asked gpt 'how super secure aws k8s for complex 900 node nextjs microservice setup thanks!'.
chilldsgn · a month ago
omg. this is what it's currently like at work. and i was told not to bring up coding standards in retrospectives. yes, i am salty AF about this. i'm dying inside.
npodbielski · a month ago
This is just work. No point in dying over this.
card_zero · a month ago
I enjoyed the concept of "a complication step". Can't see the results of changes until my code has finished complicating.
jimniels · a month ago
Author here: I didn’t realize that misspelling until now. But I like it. Gonna leave it. Thanks for pointing it out ha!
teddyh · a month ago
The medium is the massage.
throw-qqqqq · a month ago
Haha I’m not sure if the compilation/complication mixup was intentional, but it made me laugh :D
Towaway69 · a month ago
AI hallucinations again ;)
anonzzzies · a month ago
Pro tip to get ahead and get all this and more for free: use nextjs and prisma. Guaranteed pain and misery; because they move fast and break things, you can look forward to weekly vunerabilities and breaking changes!
crinkly · a month ago
We are good at not even getting that far. Have a platform team and spent a month setting up CI, github repo, onboarding, writing terraform and stuff and not even get around to doing a web site in the first place!
TheOtherHobbes · a month ago
But only after marketing, management, and other stakeholders have spent six months defining what the site should do and what it should look like, based on vibes and personal preferences. ("I like this one. Make it look like this.")