Skip Navigation

I wish writing SQL queries was more popular than ORMs

Some backend libraries let you write SQL queries as they are and deliver them to the database. They still handle making the connection, pooling, etc.

ORMs introduce a different API for making SQL queries, with the aim to make it easier. But I find them always subpar to SQL, and often times they miss advanced features (and sometimes not even those advanced).

It also means every time I use a ORM, I have to learn this ORM's API.

SQL is already a high level language abstracting inner workings of the database. So I find the promise of ease of use not to beat SQL. And I don't like abstracting an already high level abstraction.

Alright, I admit, there are a few advantages:

  • if I don't know SQL and don't plan on learning it, it is easier to learn a ORM
  • if I want better out of the box syntax highlighting (as SQL queries may be interpreted as pure strings)
  • if I want to use structures similar to my programming language (classes, functions, etc).

But ultimately I find these benefits far outweighed by the benefits of pure sql.

63 comments
  • I'm also a big fan of raw SQL. Most ORMs are fine for CRUD stuff, but the moment you want to start using the "relational" part of the database (which... that's the whole point) they start to irritate me. They also aren't free - if you're lucky, you pay at comptime (Rust's Diesel) but I think a lot of ORMs do everything at runtime via reflection and the like.

    For CRUD stuff, I usually just define some interface(s) that take a query and manually bind/extract struct fields. This definitely wouldn't scale, but it's fine when you only a handful of tables and it keeps the abstraction/performance tradeoff low.

  • I once had a task stripping a ODM out of a large project, reverting to the native driver, because of its (extremely) poor performance. Also the fun of profiling the project to prove the ODM was to blame. I also empathize with the "supposed to make things simpler, makes them more complicated instead" point you make.

    From many experiences, I hate ORM/ODMs and am immediately suspicious of anyone who likes them.

  • TL;DR you can't be an expert at every aspect of coding, so I let the big boys handle SQL and don't torture the world with my abysmal SQL code.

    I've seen enough bad SQL to claim you're wrong (I write bad SQL myself, so if you write SQL like I do, you're bad at it).

    Seriously, the large majority of devs write terrible SQL and don't know how to optimise queries in any way. They just mash together a query with whichever JOIN they learned first. NATURAL JOIN? Sure, don't mind if I do! Might end up being a LEFT JOIN, RIGHT JOIN, or INNER JOIN, but at least I got my data back right? Off the top of your head, do you know all the joins that exist, when to use which one, and which ones are aliases for another? Do you know how to write optimal JOINs when querying data with multiple relations?

    When writing similar queries, do you think most are going to copy-paste something that worked and adapt it? What if you find out that it could be optimised? Then you'll have to search for all queries that look somewhat similar and fix those.

    When you create an index for a table, are you going to tell me you are going to read up on the different types each time to make sure you're using the one that makes sense? Postgres has 6, MySQL only has 2 tbf depending on storage engine, but what about other DBs? If you write something for one DB and a client or user wants to host it with another, what will your code look like afterwards?

    Others have brought up models in code, so that's already discussed, but what about migrations? Do you think it's time well-spent writing every single migration yourself? I had the distinct pleasure of having to deal with hand-written migrations that were copy-pasted and modified columns that had nothing to do with the changed models, weren't in a transaction, failed half-way through, and tracking down which migration had actually failed. These were seasoned developers who completely forgot to put any migration in transactions. They had to learn the hard way.

  • Hmmm

    I worked on one project only which used what I guess is an ORM-like pattern, and I have to say it was actually really nice. The code was Javascript, and there was a mapping:

    • Class <-> DB table
    • Field <-> DB column
    • Row <-> Object

    For each class, there was a big mapping table which indicated which database-backed fields needed to exist in that class, and then there was automated code that (1) could create or update the database to match the specified schema (2) would create helper methods in each class for basic data functions -- the options being "Create me a new non-database-backed object X" "I've set up the new object, insert it into the DB" "give me an iterator of all database-backed objects matching this arbitrary query", "update the appropriate row with the changes I've made to this object", "delete this object from the DB," and "I'm doing something unusual, just run this SQL query".

    I honestly really liked it, it made things smooth. Maybe it was the lack of hesitation about dropping back to SQL for stuff where you needed SQL, but I never had issues with it and it seemed to me like it made life pretty straightforward.

  • ORMs introduce a different API for making SQL queries, with the aim to make it easier.

    I wouldn't say that, but instead, that they strive to keep everything contained in one language/stack/deployment workflow, with the benefit of code reusability (for instance, it's completely idiotic, if you ask me, that your models' definition and validation code get duplicated in 3 different application layers (front/API/DB) in as many different languages.

    ORMs are not a 100% solution, but do wonders for the first 98% while providing escape hatches for whatever weird case you might encounter, and are overall a net positive in my book. Moreover, while I totally agree that having DB/storage-layer knowledge is super valuable, SQL isn't exactly a flawless language and there's been about 50 years of programming language research since it was invented.

  • Check out Elixir's Ecto. You basically do write SQL for querying, it's just lightly wrapped in a functional approach.

63 comments