Hacker News new | ask | show | jobs
by melony 1451 days ago
Go needs a better ORM story, it is unfortunate Prisma abandoned their Go port.
7 comments

SQL is an incredible language with decades of theory and implementation behind it. I have never found an ORM to be better or faster or more useful than hand-written SQL for anything but the simplest of queries, and even then the benefit is debatable.
99% of a CRUD app -- which is most of them -- is going to be simple CRUD stuff. Load a thing from database, let user edit it, save it. Doing that in 'plain' sql, even with templating, is repetitive and error prone.

An ORM that didn't let you escape to SQL when you wanted to do more complex things would be a total failure, of course -- but to suggest that they're not more convenient for the 80/20 or even 90/10 use case is just really hard to understand. Must be NIH syndrome.

| Must be NIH syndrome.

I strongly disagree that not wanting to add yet another abstraction layer onto a proven technology would be NIH.

If you're using postgres, I'm a major fan of the anti-ORM (ROM?) that is sqlc. Nothing I've used comes in Go close in productivity or safety (and ability to write proper queries but use them very simply, and stay up-to-date without too much extra toil). Last I checked they're also working on adding sqlite support.

https://github.com/kyleconroy/sqlc/

They're on top of my list to add to Copper. As soon as we get sqlite support!
As the post you're replying to describes, magic is antithetical to Go idioms. An ORM is basically database-as-magic, every ORM in Go is just a nightmare.

Something like sqlc[0] is leagues better than any ORM in terms of simplicity, complexity and maintainability.

0: https://github.com/kyleconroy/sqlc

ORM's help do simple stuff well enough, but they sure make hard tasks harder. Ever try to construct a 30 line report query using this years language flavor of an ORM?

https://sqlc.dev/ makes your SQL the focus, not your Go-specific query code.

Lots of ORMS have an escape to SQL for querying, or you can choose to ignore the ORM for querying. As an example, ActiveRecord allows you to do this:

  Client.find_by_sql("
  SELECT * FROM clients
  INNER JOIN orders ON clients.id = orders.client_id
  ORDER BY clients.created_at desc
  ")
Which returns Client objects. Insert your own vastly more complex query above.
I think an ORM like https://github.com/xo/xo with https://sqlc.dev/ as a fallback for complex queries will be a killer combo!
Two high level abstractions that compile into another high level abstraction called SQL.

Why increase the complexity of something that's already a high level abstraction? Abstractions are about simplification. An orm and sqlc are not it.

https://sqlc.dev/ is not an ORM. It's not an abstraction over SQL. It is a brilliant way to make SQL the focus of your models by generating the code from your SQL, instead of the other way around.
Ah I see. My mistake.
What about the Ent ORM library?

https://entgo.io/

Ent can replace an ORM in your architecture, and it's easiest to explain in two seconds as "an ORM for Go", but it's not really that. It's a way to describe a persistent object graph, without any reference to persistence or mapping details. When your chosen persistence layer is an RDBMS, as it often is, then it uses an ORM - but you rarely interact with it at that level even when specify your entity schemas. You can back it with an object DB or REST API instead and then it wouldn't need the RM part at all.
Orms are a huge mistake.

SQL is already a very high level API that compiles to low level algorithms? Why put another very high level API on top of that?

To top it off SQL is a leaky abstraction by nature. Two high level SQL queries with equivalent results can both compile into algorithms with COMPLETELY different performance profiles. You have to manipulate the SQL query to generate the correct performance profile. This means understanding things below the SQL abstraction.

You put a ORM or any new abstraction on top of that guess what? That abstraction must compile into hacked SQL. You have to be able to manipulate the ORM such that it generates the correct SQL such that the correct SQL generates the algorithm with the correct performance profile. The leak from the sql abstraction must propogate into the ORM layer which in itself must be a leaky abstraction. It's like dealing with a leaky pipe embedded within another leaky pipe.

Optimizing SQL is already a domain knowledge thing. Now you have to use new tricks to optimize the abstraction on top of it. Two Leaky abstractions on top of each other and both very high level is a bit of a head scratcher.

Why do people even make these abstractions that only make life harder? I think it's an illusion. It's to satisfy an OCD thing but people don't realize the OCD is an illusion. People want to deal with a single language, not have strings of another language living in the code. For example, SQL strings are seemingly kind of ugly in something like GO code.

Databases are the classic bottleneck of web development in terms of speed. Optimization is a very important part of writing SQL queries as a result. Having orms and other high level abstractions on top of this area is much much more harmful then it otherwise would be if databases did not exist in this bottle-necked area of web development.

In actuality it's also questionable whether or not a leaky abstraction in the first place was the right design decision. Is SQL the right abstraction for database queries? Or should we design another high level API that has a more 1 to 1 correspondence with optimization as in a High level API that's not leaky, like What Rust is to systems programming.