Skip to content

Instantly share code, notes, and snippets.

@twolfson
Last active December 28, 2019 22:38
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twolfson/13eeeb547271c8ee32707f7b02c2ed90 to your computer and use it in GitHub Desktop.
Save twolfson/13eeeb547271c8ee32707f7b02c2ed90 to your computer and use it in GitHub Desktop.
Node.js ORM evaluation

We are planning on building a Node.js service. Here's our evaluation of the current ORM landscape:

Last updated: May 2 2016

Our likely choice is sequelize (possibly with callback bindings via bluebird-nodeify)

@lehni
Copy link

lehni commented Oct 20, 2018

@twolfson I randomly found this extensive list. Great work. But I would like to point out that I don't agree about your bad points regarding Objection.js: After working with it quite extensively I can say that the API is extremely well designed and easy to use. I also see the fact that it goes all in with promises a sign that it is future proof, not a hinderance. It's time to say goodbye to callback hell...

@hassan-jahan
Copy link

I do agree with lehni

@vjpr
Copy link

vjpr commented Nov 19, 2018

I also agree.

@naddison36
Copy link

Sequelize is also promise based.
Objection.js's support for document storage (arrays and objects in a record) wins it for me. Especially since I'm using Postgres which has jsonb datatypes https://vincit.github.io/objection.js/#documents

@toymachiner62
Copy link

Sequelize is absolutely terrible when it comes to trying to do anything with associations. They never work, take wayyyyy more code than to write queries and do all the validation, etc yourself, not very active on slack, and the documentation is dog shit. Save yourself the headache unless you are no tables that are associated to each other.

@BambiHaber
Copy link

I agree with the problems on Sequelize, it seems to be a nice library when it comes to documentation but nothing works afterwards when trying to associate.

@loudwinston
Copy link

I'd also concur RE: Sequelize and associations. Doing the simplest things (association via a join table, sort by a column in the join table) is quite difficult, and their documentation is really lacking.

We're considering a move away from Sequelize because of these issues. Objection.js looks promising

@heisian
Copy link

heisian commented Mar 7, 2019

Objection is much better architected than Sequelize. Objection is based off of Laravel's Eloquent, which is based off of Rails' ActiveRecord. Both pieces of software are very good. Objection is easily extensible due to its class-based architecture.

Many other users who've had experience in both Sequelize and Objection.js (as I have) are in the same boat: Vincit/objection.js#1069

@aprat84
Copy link

aprat84 commented Apr 4, 2019

Should also consider TypeORM.

@stalniy
Copy link

stalniy commented Apr 7, 2019

@jamespedid
Copy link

jamespedid commented Apr 11, 2019

I can't fathom how anyone would say that Objection is a good ORM and Sequelize is a bad ORM. Objection has so many bad practices going for it, it's practically a nightmare. Now there is a disclaimer that I've used Sequelize for much longer than Objection, but just from an API perspective I absolutely loathe Objection. Building it as an extension to Knex.js is just a terrible idea for an ORM.

For those who are having trouble with Sequelize's ORM for associations, what is difficult about:

const { Product, Order } = sequelize.models;
MyModel.findAll({
    include: [{
        model: Order,
        as: 'orders'
    }]
})

Hell, even if you have to do three or four associations deep, it isn't hard because you just add more objects with more includes. Constrast that to Objections, where I have to lay out the join ahead of time. Add in some goofy relationship 'magic' and you have a mess on your hands.

Raw SQL? Sequelize makes it a breeze to execute a raw query and map them to a model. And the queries that Sequelize generate typically are good (except for a few questionable subquery choices, but you can remedy these with a simple subQuery: true option.)

@elhigu
Copy link

elhigu commented Apr 14, 2019

Objection has so many bad practices going for it, it's practically a nightmare.

Please elaborate. I haven't got chance to hear any negative critic about it and that would be really valuable. Only thing I could think of is that it promotes using knex migrations which are not really nice.

@koskimas
Copy link

@jamespedid Here's the objection equivalent of your example.

const { MyModel } = require('./models/MyModel')

MyModel.query().eager('orders')

here's a four layers deep association fetch

const { MyModel } = require('./models/MyModel')

MyModel.query().eager('orders.someRelation.somethingElse.evenDeeperRelation')

Could you please elaborate what you mean by goofy magic and stuff?

@jamespedid
Copy link

First goofy thing: 'orders' is the name of the SQL table. Why am i littering everywhere in my code with the names of tables? Isn't the ORM supposed to abstract away such details? Even worse, what if I have to change the table in the database? Not unheard of, pretty common as applications tend to age actually. Maybe I'm refactoring and moving schemas. Having implementation details of the database bleed into my code everywhere is a huge problem for me.

Second goofy thing: the awkward DSL of using something like '[why,is,this,an,array,in,a,string]' to eagerly fetch over these entities? Again, incredibly hard to work with in a long-term setting. Having tokenizable, refactorable pieces in a way that is convenient is a big deal. I could use something like [${Why.tableName},${Is.tableName},...], but this is already becoming far more cumbersome than sequelize.

Copy link

ghost commented May 12, 2019

@jamespedid orders is not the SQL table name, it is the relation name defined under MyModel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment