Hacker News new | past | comments | ask | show | jobs | submit login

Couldn't agree with this more. The way I like to put it is "ORMs make the easy parts slightly easier, but they make the hard parts really hard". But I don't care that much about improving the easy parts, because they're already easy! Yet I can remember plenty of times when ORMs made my job a million times more difficult and all I was doing was fighting with the ORM itself (and usually at the worst time, e.g. when a query reached enough scale that it "fell over").

Query builders aren't exactly the same thing, but I love this article, https://gajus.medium.com/stop-using-knex-js-and-earn-30-bf41..., and it's made me a huge fan of Slonik and similar technologies. It does 90% of what I want a query builder or ORM to do (e.g. automatic binding of results to objects, strong type checking, etc.), but it lets me just write normal SQL. I also never understood this idea that SQL is some mystically difficult language. It has warts from being old, sure, but I'd rather learn SQL than whatever custom-flavor-of-ORM-query-language some ORM tool created.




> but I'd rather learn SQL than whatever custom-flavor-of-ORM-query-language some ORM tool created

This point is worth emphasizing!

When you application carries non-trivial business logic, it will create non-trivial DB access patterns.

The developer will either use SQL or some other language that, pragmatically speaking, translates to SQL. But either way, they will learn some DB expression.

I'd rather use a standard. Existing familiarity, easier to find docs, support, and is probably more bug-free, etc.


And since SQL has existed for so long, chances are that someone already had your problem and has posted the solution somewhere.


Another reason to use standard MySQL? ChatGPT is really good at writing, and modifying, SQL queries and the code that injects input into it.

You don't really have to write SQL anymore, you just tell chatgpt what you want changed and it works most the time. The times it doesn't, it gets you most of the way there.


Not sure "standard" and "MySQL" belong in the same sentence. ;-)


> The times it doesn't, it gets you most of the way there.

But you have to understand SQL to know that, and to fix it, which defeats the purpose really.


I wouldn’t say that it defeats the purpose really, as it’s a great aid to help us reach the proper solution.


I can imagine what would be/is valuable is type checked embedded SQL queries.



The problem is the ORM requires you to know its language, the underlying SQL for that database, as well as how the ORM maps to that underlying language.

It’s the worst of a leaky abstraction, and like 3x the conceptual overhead. But it’s better because … something something OOP.


> It’s the worst of a leaky abstraction, and like 3x the conceptual overhead.

I really think you hit the nail on the head with this sentence. For example, another commenter said "But the same SQL fanboys who believe every developer ought to memorize tri-state truth tables..."

Yes, I think it's fine to argue that the boolean logic with respect to NULL in SQL is a pain in the ass. But ORMs certainly don't hide that from you! The ways DBs treat nulls is a fundamental part of nearly all RDBMSes - if you don't understand that, you're (eventually) going to have a bad time. All ORMs really do is make it harder to understand when you may need to take special null logic into account.


Exactly. As unfortunate as those warts are, you can't pretend them away. Might as well be able to see them clearly.


“Something something OOP” - you reach enlightenment once you realize OOP itself is an anti-pattern.


OOP isn't an anti pattern, OOP as a _silver bullet_ is an anti pattern. Almost all of my programs end up to some degree multi paradigm of OOP, functional, and procedural.


I call that post-OOP. The outcome might even be very, very similar to what you might have implemented as an OOP believer, but the assessment has flipped: instead of assuming yourself "did I use enough OOPisms" you ask yourself "could it be better with less?"


I'm not gonna argue against OOP in general here, but in the context of ORMs, some of the most important characteristics of OOP (encapsulation and inheritance, especially) are the source of many anti-patterns.

Keeping methods that operate on data together with the data is the biggest problem with the Active Record pattern, and it's good that some new ORMs (like Ecto) are inspiring others to try other alternatives. Those alternatives invariably eschew the exaggerated use of method/data coupling and code-sharing via inheritance/mixins, among other things. They are either functional or procedural.

Not to mention that a lot of OOP-heavy codebases are already replacing a lot of OOP-heavy ORM code with procedural (Services) or functional-inspired ("Railway Oriented Programming", Trailblazer operations).

Sure, there are still classes being used. But I don't think it's fair to call "just using classes" as really as OOP, when they're used as structs, and especially in languages that make class usage mandatory.


I dunno I've been using rails for over a decade, its lovely.


I never said otherwise. “Lovely” and “the ORM is free of issues” is orthogonal. The issues are why there’s a lot of different alternative ways of writing domain logic in Rails.


I agree. We'd be better off with data structures and functions that work on those data structures, and packages/modules/namespaces (with public/private exposing) to do encapsulation.

OOP comes with the banana-gorilla-jungle problem, which I consider the fundamental issue with it.

https://softwareengineering.stackexchange.com/questions/3687...


> It’s the worst of a leaky abstraction

This stems from the fact that SQL itself is a very leaky abstraction: each RDBMS implementation is different, and the common part is shallow. There is no way to optimize a query in an RDBMS-agnostic way.

Actually, ORMs are worse than a leaky abstraction: they border on cheating! They actually abstract the easy, boring part away, but they run with their tail between their legs as soon as the issue becomes interesting.


> They actually abstract the easy, boring part away, but they run with their tail between their legs as soon as the issue becomes interesting.

This is the biggest offense, IMO. It's not just that ORMs are a leaky abstraction, it's that they're just a bad abstraction--leaky or not. We don't really need an abstraction to make easy things easier, and we certainly don't need/want an abstraction that makes hard things even harder!

There's a famous quote that always comes to mind when I encounter stuff like this. I've seen it attributed to several people, so I'm not positive, but I think it was from Larry Wall: "Make easy things easy and hard things possible."


Exactly!

The analogy I use is SQL is like two-wheeled motorbike - fast, nimble, elegant. Yes, it may be dangerous. Yes, you may need to wear a helmet. Yes, it cannot carry too much load. But it gets you very quickly very far, if you have skill!

Now, ORM sees deficiencies and presents you... two motorbikes welded together side-by-side by some iron sticks. They call it a "car". Four wheels are better than two, right? Two engines can push more load, right? No helmet needed, right?

But does it really become a "car", or it is just has most of deficiencies of the motorbike plus some spectacular new ones? And no benefits of a car whatsoever?

I run away in disgust.


Django's magic double underscored kwargs DSL is so awful.

Just let me write SQL, please. God I miss JDBI


> Django's magic is so awful.

Fixed that for you.

Granted, I haven't dove deep into Django, but from what I learned scratching the surface, it's slow, bloated, utterly un-Pythonic, and I just don't understand how it got so popular. Yeah, it's the most batteries-included web app framework for Python, but it just sucks to use.


Yep, fair fix. My favourite bit of Django metabollocks is when they mix in an override for __new__ on models, that won't let you instantiate an instance if the Django "app" the model or any of its dependencies belong to isn't in django.settings.INSTALLED_APPs.

I'm sure they had a good reason for doing this at some point, but I'm just trying to write a unit test for something that consumes a FooModel, no DB access needed, just a small test that doesn't involve starting up all the Django bits, but Django says no, best I can do is creating an SQLite DB and creating all your tables on it.

I have toyed with doing my own metabollocks hackery to circumvent this, but it just makes everything even more fragile.

(Oh, the Django test-runner won't discover tests that aren't subclasses of a Django test class, so no writing a unittest.TestCase for you! You might need Django in it!)


> I'd rather learn SQL than whatever custom-flavor-of-ORM-query-language some ORM tool created.

Me too! That's why I use an ORM that lets you write queries in SQL, like... Hibernate.

This narrative seems to come up frequently. People make (good) arguments against certain features of ORMs and then conclude it's an argument against ORMs in general. The boundary between databases and codebases is very broad. But ultimately you work with objects in your code, and relational tables in your database, so there's going to be some sort of Object Relational Mapper in between.


> Me too! That's why I use an ORM that lets you write queries in SQL, like... Hibernate.

Yeah, this criticism of ORMs strikes me as off-base. I feel like any ORM worth its salt gives you the tools to write raw SQL as needed, which can also be combined with the query builder the ORM uses.

I use Rails/ActiveRecord and have very few complaints. When I need to do something simple, the convenience methods work great. When I need a complex query, I just write it.

There's a learning curve here, where you have to understand when to "break glass" for writing queries directly (either for better performance reasons or because an ORM lacks the expressiveness required).

I think a lot of ORM hate comes from people who never got deep enough to really hit the sweet spot. They (correctly) note that the ORM abstractions aren't suitable for every query, but (IMO) they disregard the benefits that they provide for most queries. If something like 90% of my queries can be generated by an ORM, I'm feeling pretty good about that - it's a lot more maintainable.


> I think a lot of ORM hate comes from people who never got deep enough to really hit the sweet spot.

This. And also, the feel of using Rails/ActiveRecord resonates with me in a way that no other ORM I've used does. It's not just the ORM but the tooling around it esp. wrt generating migrations, scaffolding and so on.

> There's a learning curve here, where you have to understand when to "break glass" for writing queries directly.

Yep. ORM is a tool. The craftsperson needs to acquire skill both in using the tool and in knowing when to reach for another tool.

Maybe some people feel ORM is never the right tool. Who can argue with that? I'm curious to see how they do it. Maybe I'll learn something.


> ultimately you work with objects in your code, and relational tables in your database

Yes, you can map a record in a DB table to a class, and as long as you are happy with retrieving records (and related records) and mapping them to classes, an ORM will be all you need. But SQL is not just limited to the columns of a table, you can join, define new columns in your select statement, group, use aggregate functions etc. etc., and then you quickly get into territory that the ORM doesn't understand anymore. So the point that ORMs take away a lot of the flexibility that SQL gives you still stands...


This is not an objection to ORMs, except perhaps very simplistic ones. The ORMs I'm familiar with let you map queries to arbitrary objects. I use CTEs, joins, groups, aggregations, custom columns, etc in SQL queries (with Hibernate) all the time.


But... At that point what does hibernate even do for you? You can just use a lighter query wrapper at that point, or almost even roll your own wrapper around jdbc directly. The latter is a bit more work but it might be worth it depending on project since it gives you absolute control.

I'll take a query wrapper that's designed so I supply queries directly and it does the work from there (binding to objects) over using hibernate that way any time.


Having seen quite a lot of 'roll your own' solutions for wrapping queries: they were almost all unstable, inefficient messes that have a tendency to pick up lots of ad-hoc functionality. I'm not particularly fond of Hibernate but at least it's well tested and efficient for what it does and does things in a standard way so you can mostly look up stuff in the manual instead of guessing your way through a homebuilt framework.


> depending on project since it gives you absolute control

Absolute control to hunt down your own bugs, instead of using something that is an industry standard and any competent programmer jumping to your project can be up-to-speed with it instantly..


Very few developers are competent with hibernate, many fewer than with sql. Writeback cache nature of hibernate makes it very complex, order of operations on the app won't match order of operations in the DB.


Even an "industry standard" framework can get in the way. Given the constraints of executing efficient queries; handling errors and timeouts on the application's terms; and enforcing concurrency and transaction handling policies even a "good" ORM can be more a problem than a solution.


All of those will be worse off by hand-made “solutions”. Especially that you are not forced to use ORM for everything. Use it for like 90% of your generic db usage, and use its in-built escape hatches for the rest, like native queries or go straight to the db driver if needed.


In my experience I‘m better off not touching an ORM at all


I agree that ORMs are bad, but disagree in that I think that SQL is also bad--it has this bizarre natural-ish language syntax that is inconsistent and often difficult to reason about, with a huge number of keywords (including many that are noise-only). I would welcome a simple, modern alternative to SQL. I think the fact that people keep building and using ORMs is evidence that SQL is difficult to use.


This post about "PRQL" got a ton of upvotes when it was posted on HN last year: https://news.ycombinator.com/item?id=30060784

In general, one of the thing I hate most about SQL is "the order of clauses is wrong" (should really start with the FROM clause and end with SELECT, see https://news.ycombinator.com/item?id=21150606), and PRQL fixes that.


And if that's the biggest perceived problem with SQL, then SQL isn't going anywhere.

It can't just be a little better than SQL, especially in terms of syntactic aesthetics; it has to be substantially and provably better than SQL to the point where companies are willing to pay for retraining, folks are willing to buy books and classes about it, and database engine developers have to consider it worthwhile to implement.

I don't see PRQL coming close to reaching that bar.


It's not a problem with SQL. For example, in ClickHouse, you can write FROM table SELECT ... But this is not a big deal.


But at that point, it’s no longer SQL, it’s something better. That seems like a very nice point in favor of Clickhouse! But then again, Clickhouse is not a RDBMS, right?


Agreed! First time I used the postgres Node library [0], I was sold!

[0] https://github.com/porsager/postgres




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: