Live data from Hacker News

Our journey in dropping the ORM in Go

alanilling.medium.com

61–70 of 157 posts

Re: Our journey in dropping the ORM in Go

#61
post #60
post #56

Earlier quoted context omitted.

Can you provide some examples? I use sqlalchemy, and the amount of work that it does for me when it comes to handling mutating data is pretty remarkable.

No real specifics, but I usually run into ORM in the context of I'm the person on the team with experience running MySQL and someone has a slow query. When they're hand built queries, I can usually provide a query or sequence of queries that provides the same data without knocking the server over and it gets put into production within the same day. When they're ORM, it takes days to find the query, and then more days…

Yeah, I remember now the pain of using bad orms. That feeling that you know what you want, but it’s going to load the data via configuration that you can’t bend into shape.

Sqlalchemy is not that kind of orm. If anything is running slow in production I can find it from the logs and then track it to the code quickly - then you can do any sort of query you want in its place. For me it’s never the orm loading stuff that’s slow, it’s always the more complicated queries we’ve done for reporting or whatever.

Re: Our journey in dropping the ORM in Go

#62
post #18

This article would have been better without the unnecessary war analogy and history lesson.

Indeed the analogy has not aged well. It's in bad taste, and somewhat offensive, to hear the term "Vietnam of programming".

Why did it not age well? Are there any new findings regarding Vietnam?

Re: Our journey in dropping the ORM in Go

#64
post #9

Never understood the hate for ORMs. I need to map from my data storage to my domain model somehow, why write all that code myself

Because relational databases are very good at (surprise!) relations. So in SQL you can query data from several joined tables, query only certain columns, aggregate columns etc. etc. And all of these things are made needlessly complicated by using ORM. Even with the best ORM, you still have to learn an arcane new syntax for stuff you could write in 30 seconds when using SQL...

Right, but for most of that stuff I can just write a one-off query, munge it into the ORM's objects and pass that off to my view for rendering. But probably 80% of my queries are "get this object by ID" or "get these objects and some related ones by a simple condition" or maybe a slightly complex condition. In these cases an ORM works wonders and has almost zero downsides

Re: Our journey in dropping the ORM in Go

#65

Never understood the hate for ORMs. I need to map from my data storage to my domain model somehow, why write all that code myself

Is writing SQL query templates too much? The only valid advantage of ORM is to prevent SQL injection, which can be solved with prepared statement.

Okay so I write a prepared statement, send it to my database with some parameters, and get back some rows. Now what? How do I turn those rows into structs or objects or whatever that I can pass around for business logic? Maybe I write a function that takes a row and maps it to an object, I call that for every row I get back, whatever. Oh but now I'm joining a belongs-to relationship and I want that joined row represented as an object, too, so I have to write a function to convert that row and oh what if the fields have conflicting names okay I can always prefix them with the name of the table and wait sometimes I'm not querying with this related object so I have to check if the related id is included in the row and... on and on and on for every possible way I could make a different query.

Great, now I've basically reinvented an ORM but it's worse because I have to manually maintain all this mapper code and it only ever accounts for the cases I've considered. If I make it fully generic, then I've really just reinvented an ORM.

Re: Our journey in dropping the ORM in Go

#66
post #21

Never understood the hate for ORMs. I need to map from my data storage to my domain model somehow, why write all that code myself

> Never understood the hate for ORMs. I need to map from my data storage to my domain model somehow, why write all that code myself This is addressed in the article the title of this one refers to, "The Vietnam of Computer Science" [1]. I really recommend reading it in order to understand why the "obvious" solution is not always the best fit, but the very short summary is: due to the Object-Relational Impedance Misma…

It's no wonder this article was written in 2006. One of the problems describes DBAs! Has anyone heard of a DBA in the last decade?

Most of these other problems are just... solved? Any decent language will let you override the meaning of equality between two objects, if you don't use a ton of inheritance the inheritance problem won't bite you, good libraries let you describe the schema once and either generate SQL or generate classes, etc.

Re: Our journey in dropping the ORM in Go

#67

Earlier quoted context omitted.

Indeed the analogy has not aged well. It's in bad taste, and somewhat offensive, to hear the term "Vietnam of programming".

Why did it not age well? Are there any new findings regarding Vietnam?

To most people in the world, "Vietnam" is not a war, and is not merely a symbol of absurdly misconceived incompetence.

Re: Our journey in dropping the ORM in Go

#68
post #51

Earlier quoted context omitted.

> I write a view for each access method (so I can change the schema without worrying about changing every access method), and a function for each update/insert/delete (for the same reasons). God how I hate supporting such architecture. It loses edit history unless you're very careful (which many developers are not) and do absolutely every piece of DDL in a versioned migration, and makes DDL extremely painful because…

We’ve started using views and friends a lot more recently (now I’ve recovered from my PTSD from a lifetime ago when I worked in a poorly managed sql server shop). As you point out, they’re often not first class citizens. On the flip side, we’ve just moved ours to files on disk (one per object) and hacked in some tooling to autogenerate the migrations from them (we use alembic / sqlalchemy which already does a good jo…

this. Don't write your SQL into the database. Write them as scripts (starting with "drop XYX", then "create XYZ", check them into git, and treat them as code.

Migrations are for schema changes. Views and functions are not schema.

Re: Our journey in dropping the ORM in Go

#69
post #6

So frustrating. You got like 80% of the way there, and then went "nope, too much work" and diverted to add more complexity. The answer is to write the SQL yourself, and the scan methods yourself. Code generation is better than ORM, but still a wrapper, still adds complexity, and still brings problems. Yes it's a pain in the arse to write all that boilerplate in one go (pun intended). But if you'd started without an O…

> I write a view for each access method (so I can change the schema without worrying about changing every access method), and a function for each update/insert/delete (for the same reasons). Database view and stored procedures?

yeah. Postgres has functions, SQL Server has sprocs.

Re: Our journey in dropping the ORM in Go

#70
post #52

Earlier quoted context omitted.

ORM is that one layer that fails to abstract anything substantial yet whose existence is intrusive enough to annoy people. The worst example of leaky abstraction.

ORM makes the easy things easier and the hard things harder. No thanks.

So choose an ORM that lets you easily drop down to plain SQL in the rare cases where it's necessary and you get the best of both worlds.
Post reply on HN