Live data from Hacker News

To ORM or Not to ORM

eli.thegreenplace.net

71–80 of 300 posts

Re: To ORM or Not to ORM

#71

Earlier quoted context omitted.

You forgot to add an index on tags.name and null constraints on the rest of the columns. > from there it's just regular rails That's the problem. Examples like this focus on the first few minutes of development. Not the subsequent years of maintenance.

I stayed close to what the author did. adding an index: add_index :tags, :name adding a null constraint: change_column :tags, :name, :string, null: false validates :name, presence: true # for proper validations https://github.com/localhostdotdev/bug/commit/3765237008c36c...

> I stayed close to what the author did.

Fair enough. I’ll concede that wasn’t a fair comparison to the OP. My point remains that examples focusing on the initial setup are uninteresting (to me) because that’s not where the bulk of the work is.

Re: To ORM or Not to ORM

#72
post #64

Earlier quoted context omitted.

Until you want to be able to sort and filter and do all of the other things that most CRUD applications do. Once you're there, if you're doing SQL directly, now you're manipulating strings in your code, instead of being able to build some kind of object that then generates a query for you.

It sounds like you are conflating an ORMs with query builders?

Query builders and ORMs often go hand in hand in my experience, as the ORM will expose the ability to perform custom querying capabilities around the specific object you're working with; however, you're correct in that I am more considering query builders than ORMs directly in this instance.

Re: To ORM or Not to ORM

#73
post #53
post #4

Earlier quoted context omitted.

All the time allegedly saved is also more than compensated for when the ORM makes bad queries that are roughly impossible to fix.

Frequently the easiest path to perform a complex query with an ORM results in N+1 performance disasters. The inevitable retort is something like "but the ORM has better ways to do that." Of course it does; ORM implementers aren't incompetent. The key word is "easiest," meaning the ORM user doesn't have to spend time learning anything beyond simply chaining method calls. In production such work goes haywire when resol…

I look at this as not playing to core competencies.

SQL's strength is that it's declarative.

By wrapping an ORM around it, suddenly you have a DB engine talking to an ORM engine through a declarative interface. There simply isn't enough information and context passed across the interface to properly optimize.

So in the end, it's like trying to run two optimizing compilers in series, where either knows the specs of the other.

Re: To ORM or Not to ORM

#74

While I learn towards not using an ORM, the productivity gains (at the very least early on in development) are undeniable. What I've always looked for are frameworks that give you an ORM but also make lower level queries very easy, normally via a query builder, allowing you to go back and forth between levels of abstraction. If I had to choose, I prefer libraries that give you the lower level of abstractions first an…

Have you looked at the DataMapper pattern? Not identical to what you are describing, but it sounds closer than a tradition ORM.

Re: To ORM or Not to ORM

#75
post #4

Sample size one 1 but ORM drives me crazy. Why can't we just use SQL? How does it save time when I have to learn the ORM language, which probably has a lot less support and users? The OP here says it "reduces boilerplate" -- rarely have I created an application and thought its biggest problem was too much boilerplate. But everyone at work loves them so I must be wrong somehow.

All the time allegedly saved is also more than compensated for when the ORM makes bad queries that are roughly impossible to fix.

I've only worked with a couple ORMs, but they all allowed me to write my own queries if I wanted to. The ORM generated 90%, but when there was a performance win I just wrote my own.

Re: To ORM or Not to ORM

#76

While I learn towards not using an ORM, the productivity gains (at the very least early on in development) are undeniable. What I've always looked for are frameworks that give you an ORM but also make lower level queries very easy, normally via a query builder, allowing you to go back and forth between levels of abstraction. If I had to choose, I prefer libraries that give you the lower level of abstractions first an…

Have you looked at the DataMapper pattern? Not identical to what you are describing, but it sounds closer than a tradition ORM.

The DataMapper pattern is very much included in the normal discussion of what an ORM is expected to provide -- so much so that almost most larger ORMs (that I know of at least) is listed on the Wiki[0], including TypeORM.

That said, you're right, the DataMapper pattern isn't quite identical, and it is a piece of fully OOP-based ORMs that I think are on the right side of the spectrum. I'd say that the DataMapper pattern fits in the middle -- I call it Serialization/Deserialization, and assuming the syncing of data is not constant (as in triggering action on another thread or something), then it can be anything from a function (ex. db::insert_user(user), user.write_to_db(db) or Adapter.save(obj)) to a dedicated object (Adapter.update(db, obj)).

If I had to try and point to a difference between the two, I'd say that DataMapper-ish or DataMapper-and-below levels of abstraction expose more internals by default (which is obvious) -- I find that ORMs on the right side of the spectrum I sketched up top try to never expose their internals, which quickly falls apart as soon as you step off the paved/well-traveled path.

[EDIT] I want to note that dealing with this syncing behavior in EF (Entity Framework) was really annoying. The constant management of a pool of objects that "reflected" the objects in the DB and had to be saved all together/flushed before they were manipulated or whatever was really annoying. That said, I am now aware that C# is one of my greatest weaknesses, so take this opinion with a grain of salt, it's entirely possible that I just didn't have the skill to do it right and keep it in my mind the right way. Just to make sure I'm not unfairly bashing EF I went and found a relevant SO post to show the kind of stuff I didn't like having to look up/deal with [1]. I'm picking on EF but this is likely an issue with any ORMs that handle it this way (w/ the object pooling & syncing).

[0]: https://en.wikipedia.org/wiki/Data_mapper_pattern

[1]: https://stackoverflow.com/questions/5462620/entity-framework...

Re: To ORM or Not to ORM

#77
post #20

I wish people did not think the choice was solely between "write raw SQL with raw strings" and "try to pretend the database is object-oriented when it is not." The third approach is to safely wrap the database and its columns with code in a way that is composable. In Python, SQLAlchemy has an ORM, but it is optional, and you can just work with tables and columns if you want.

The real third approach is that you can safely pretend the database is object-oriented for manipulation and simple lists and still use SQL for complex queries. Most ORMs let you safely mix and match both methods easily. This ORM or not ORM is the wrong question. Use an ORM to save you headaches where it's appropriate and use direct SQL when it's not.

You are absolutely correct. Using both is a very valid options.

We use ActiveRecord a lot, and then have custom SQL queries using `find_by_sql` for very complex, optimized joins. It works very well. Rails gets out of the way when we need it to.

Re: To ORM or Not to ORM

#78

While I learn towards not using an ORM, the productivity gains (at the very least early on in development) are undeniable. What I've always looked for are frameworks that give you an ORM but also make lower level queries very easy, normally via a query builder, allowing you to go back and forth between levels of abstraction. If I had to choose, I prefer libraries that give you the lower level of abstractions first an…

This is where I land also. ORM's are excellent for the repetitive stuff, especially when integrated with frameworks but I don't want the presence of an ORM to prevent me from accessing the more advanced aspects of my database. I'm a heavy Postgres user and there's just...so much that it's capable of that hiding it behind an ORM to pretend it's "just a database" is a bit like a tragedy.

One of the better balances I ever came across from multiple languages was actually ActiveRecord because of the Scopes functionality. The scopes let you abstract certain parts of queries and name them, reuse them, include parameters, combine multiples of them back together, switch parts out, etc. You can combine raw snippets with fully abstracted parts.

It's extremely flexible and probably the feature of Rails that I miss most when I don't have it.

https://guides.rubyonrails.org/active_record_querying.html#s...

Re: To ORM or Not to ORM

#79
post #20

I wish people did not think the choice was solely between "write raw SQL with raw strings" and "try to pretend the database is object-oriented when it is not." The third approach is to safely wrap the database and its columns with code in a way that is composable. In Python, SQLAlchemy has an ORM, but it is optional, and you can just work with tables and columns if you want.

> The third approach is to safely wrap the database and its columns with code in a way that is composable.

Like Haskell's Esqueleto[1] which lets you work with SQL code as Haskell functions and values. As an example from the documentation:

  select $ from $ \p -> do
    where_ (p ^. PersonAge >=. just (val 18))
    return p
results in roughly:

  SELECT * FROM Person
    WHERE Person.age >= 18
This lets you define new functions to use in your queries that use SQL functions. For example, you can define `isPrefixOf` for SQL using the SQL functions `char_length()` and `left()`. The use of the function will be expanded into the corresponding SQL code when the query runs. Like,

  select $ from $ \p -> do
    where_ $ val "John" `isPrefixOfE` p ^. PersonName
    return p
could result in:

  SELECT * FROM Person
    WHERE LEFT(Person.name, CHAR_LENGTH('John')) = 'John'
[1] https://www.stackage.org/haddock/nightly-2019-05-07/esquelet...

Re: To ORM or Not to ORM

#80
post #28

Earlier quoted context omitted.

I am very happy with ORM. I'm currently working on an e-shop. I need to display many tables with different filters. Administrator wants products starting with string? OK: if filter['category']: qs = qs.filter ... Administrator wants products without category? Ok: if filter['category']: qs = qs.filter ... Add multilang supprt? Ok: subclass model, mark fields and translatable, run migrate script I can combine any filte…

This is about the only use case where I find ORMs useful

Also a problem solved by less magic libraries, like MyBatis, jOOQ, SQLAlchemy Core, etc.
Post reply on HN