Live data from Hacker News

What ORMs have taught me: just learn SQL (2014)

wozniak.ca

81–90 of 305 posts

Re: What ORMs have taught me: just learn SQL (2014)

#81
post #46
post #37

Earlier quoted context omitted.

Here's the thing, anyone who knows SQL will find the second one readable, and only Ruby programmers who have used ActiveRecord will know how the first one does.

Really? connection.exec_, .map, .build – there's a lot more non-SQL going on in the second example than the first. The first may be syntactically far from SQL, but the use of familiar vocabulary makes it pretty understandable from a SQL point-of-view.

[deleted]

Re: What ORMs have taught me: just learn SQL (2014)

#82
post #11

Earlier quoted context omitted.

It's quite trivial to keep stored procedure code in source control with the app code or in its own repo. I am always mystified when I hear the complaint that this is difficult because in my experience it's no more difficult than managing any other code in a SCM repo.

My biggest concern has always been around zero downtime deployment with stored procedures. Your database has to work with both the old and new versions of web code during the deploy in case of rollback to make that process work and that always struck me as the weird edge case that makes things tough. If a procedure never changes or remains backward compatible then it should still be fine though.

Give the new proc a different name (e.g. append a version number). On the n+1 deployment, clean up the old proc.

Re: What ORMs have taught me: just learn SQL (2014)

#83
post #37

Earlier quoted context omitted.

I completely agree. 90% of the queries in my app are no more complex than selecting from a table with a simple condition. I definitely find users = User.where(has_foo: true).limit(10) to be a lot more readable than rows = connection.exec_query("SELECT * FROM users WHERE has_foo=true LIMIT 10") users = rows.map { |row| User.build(row) } (And that's an example with no user-provided input) Likewise, any app of sufficien…

Here's the thing, anyone who knows SQL will find the second one readable, and only Ruby programmers who have used ActiveRecord will know how the first one does.

I've never written a line of Ruby in my life and I know what that code does, because it's essentially identical to what you'd write in C# LINQ to query with Entity Framework, LINQ2SQL, etc.

    var users = Users.Where(u => u.HasFoo).Take(10);

Re: What ORMs have taught me: just learn SQL (2014)

#84
post #72

Ten years ago, there was a blog post every other week bemoaning ORM's. Ten years ago, those posts often had merit. In 2016, this sentiment is outdated. A few points: 1. If you think that using an ORM means you don't have to learn SQL, then you're going to have a bad time. This is where most of the bad press originates... from people who never really learned SQL or their chosen ORM. An ORM provides type checking at yo…

Marshalling support is useful. SQL result -> struct and struct -> SQL insert code is repetitive to write. Getting fancier than that may be overkill. Marshalling in general needs more compile-time support. Kludges such as Google protocol buffer preprocessors are a fast but clunky way to do it. It would be useful if languages could be given a reference to an SQL CREATE TABLE and could use that information usefully. Fie…

[deleted]

Re: What ORMs have taught me: just learn SQL (2014)

#85
post #37

Earlier quoted context omitted.

Here's the thing, anyone who knows SQL will find the second one readable, and only Ruby programmers who have used ActiveRecord will know how the first one does.

> and only Ruby programmers who have used ActiveRecord will know how the first one does. do you really think the first one is /that/ hard to understand?

In my experience, programmers are often very fuzzy on all of the types involved in such libraries. I don't even mean "strong typing", but just the operations that they can perform with the various chunks of that expression. This is often complicated by the fact that the library itself often has bizarre limitations that have more to do with its internal implementation and limitations than with SQL. It's rare for me to see anyone use a library like that with fluency. Which seems to me to be a valid way of saying that, yes, in practice, it does seem to be harder to understand the first version in Ruby than you might initially think. Using it isn't particularly harder, but understanding it is.

Also note this is an observation of mine, not a logical argument, so trying to logically argue about why it shouldn't be harder would be arguing a point I'm not making. As much as I don't like people bashing strings together programmatically to generate SQL queries due to the ease of screwing it up, I observe that a lot more programmers are capable of this (even if they screw up the security) than seem to understand how to use things like ActiveRecord equally fluently. YMMV.

Re: What ORMs have taught me: just learn SQL (2014)

#86
post #77

Earlier quoted context omitted.

> An ORM provides type checking at your application layer This. When composing complex queries, we really want type checking and SQL injection safety.

Don't parameterized queries provide all the safety one might need?

Parameterized queries are to prevent injection. They don't tell you, at compile time, when you're building an invalid/unrepresentable SQL query.

Re: What ORMs have taught me: just learn SQL (2014)

#87
post #5

Earlier quoted context omitted.

But how do you do: SELECT posts.*, (SELECT COUNT(1) FROM comments WHERE post_id = posts.id) AS comments_count FROM posts; In ActiveRecord, without 1+N queries, or caching comments_count in a column somewhere? Admittedly, that was not the best example. The last time I need something more intertwined than a simple COUNT in subquery, the answer was "give up and just use Arel." But at this point it is no longer quite Act…

That's really easy. Post.select("posts.*, count(comments.*) as comments_count").joins(:comments)

Wouldn't you need to do a group by in your query as well?

Re: What ORMs have taught me: just learn SQL (2014)

#88
post #61

Never seen a large enough project that relies on an ORM be anything other than a giant mess. I mean never. The conclusion is correct. From an application perspective the db is just another API and should be treated that way and the ORM should just be thought of as a convenient DSL for creating queries on top of that API.

What do you define as "large enough"? There have been a ton of fairly big Ruby on Rails apps written over the last few years, the majority of them using ActiveRecord to handle everything.

Really? How many of those backends have you seen and worked on? Heroic effort does not qualify as success in my book. You can maintain any nightmare by just throwing enough bodies at it. What counts is the maintenance burden and the cost of change.

Re: What ORMs have taught me: just learn SQL (2014)

#89
post #62

Never seen a large enough project that relies on an ORM be anything other than a giant mess. I mean never. The conclusion is correct. From an application perspective the db is just another API and should be treated that way and the ORM should just be thought of as a convenient DSL for creating queries on top of that API.

It strikes me as a thick/thin client tug of war. You can supplant ORMs by e.g. moving your logic into stored procedures on the db side, until you find an inconvenience there, then back and forth until the end of time. As with many dyadic architectural choices, there are good arguments on both sides.

I agree. The problem is that striking that balance is hard. If you go all-in with an ORM then trying to backpedal and figure out at which point you went wrong becomes almost impossible and so now you have a tangled web of ORM queries and no clear path to untangling things.

Re: What ORMs have taught me: just learn SQL (2014)

#90
post #3

I think ORMs are a great tool to get something off the ground quickly. Like with most tools you will hit a point where they make things more difficult and then it's probably time to switch to SQL only or mix SQL with ORM especially for performance critical queries. In most applications I have seen the ORM provided a lot of value but there were cases where it needed to be augmented with raw SQL. I never understand why…

I completely agree. 90% of the queries in my app are no more complex than selecting from a table with a simple condition. I definitely find users = User.where(has_foo: true).limit(10) to be a lot more readable than rows = connection.exec_query("SELECT * FROM users WHERE has_foo=true LIMIT 10") users = rows.map { |row| User.build(row) } (And that's an example with no user-provided input) Likewise, any app of sufficien…

In this example, it seems like it could be an issue that you take everything and then only use the first 10, instead of only taking the first 10 to begin with. Is there a way to not make it take them all, like putting the limit parameter in where()?
Post reply on HN