6 ms·
I've also torn it up with MikroORM this weekend. I figured I'd give my 2¢ review of ORMs in NodeJS. MikroORM: is maintained, with a lead developer who is recep
by dfee 6y ago
I've also torn it up with MikroORM this weekend. I figured I'd give my 2¢ review of ORMs in NodeJS.
MikroORM: is maintained, with a lead developer who is receptive to feedback, checks issues and responds. It's also built around the unit-of-work pattern. Unfortunately, there are some bugs – and having looked at the lack and quality of tests, this is unsurprising. Also, look at my note on type-native at the end. Ultimately, I left the weekend with the following thoughts:
1) is using an ORM in NodeJS even worth it or should I just go a level higher to Knex?
2) how smart is it to adopt a framework that may go unmaintained in the future, and is already big enough (in complexity) with a lack of quality tests and promising-but-incomplete docs? am I pointing a gun at my foot?
3) if I were going to go with an ORM in TypeScript today, this would be it. I hope that download numbers will increase, the community will get larger, and the product will continue to advance. The owner cares, but I don't think he can get there on his own.
Non-MikroORM / Community: Many of the ORMs are abandoned – this includes TypeORM, or aren't type-native [f1]. TypeORM was promising (I guess), but I'm really reluctant to work with it on even the most basic tasks. That the documentation is out of date, the issues are unresolved, and maintenance is lacking make this a no-go for me.
p.s. I do sorely miss SQLAlchemy (thanks zzzeek for those good times) when working with DBs in NodeJS.
[f1] type-native: this is actually a double edged sword. The ORM is never going to have type-parity with the underlying DB. So, you really shouldn't invest in building your "schemas" or "migration files" from type metadata. And you'll also only ever be able to type the most basic queries. I'm concerned MikroORM has gone too far down this path.
- adamsvystun 6y agoWhat do you think about Prisma? It has typescript support.
- dfee 6y agoIt does have TS support. It definitely seems pretty interesting, but there are a few reasons I wasn't ready to move on it: 1) schema generation problems (e.g. it'll rename your associations) 2) I'm reluctant to believe that I don't actually want a real query-builder beneath the ORM. (https://www.prisma.io/docs/understand-prisma/why-prisma#sql-query-builders-high-control-medium-productivity https://www.prisma.io/docs/understand-prisma/why-prisma#sql-...) 3) transaction support is experimental, and it's not /really/ what app developers mean when they say "transaction". (https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/transactions#the-transaction-api https://www.prisma.io/docs/reference/tools-and-interfaces/pr...) I think something like this might be nice as it evolves. But, I think they're taking over too much of the stack (e.g. with inner Rust bindings, and not really exposing the power-APIs) whereas with something like MikroORM you can access the underlying query builder (knex).
- 2color 6y agoThanks for sharing your thoughts. Daniel from the Prisma team here. regarding 1: Can you share more about schema generation problems? Are you using introspection to create the Prisma schema? If so, we're actively working to improve this flow with "re-introspection": https://github.com/prisma/prisma/issues/2829 https://github.com/prisma/prisma/issues/2829 Regarding 3: Prisma supports transactions with nested writes and it's stable (https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/transactions#how-prisma-client-supports-transactions-today https://www.prisma.io/docs/reference/tools-and-interfaces/pr...). The new experimental transaction API pushes the idea of transactions further by combining multiple individual Prisma Client calls into a transaction. Long running transactions are indeed not supported. Long-running transactions require holding a stateful connection open between two components for an extended period of time which can be at odds with the way modern scalable systems are built. Perhaps you can share more what you/app developers mean by transaction?
- dfee 6y agoHey dude! 1) schema-generation: uh, I can't find the video anymore! But basically (https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-migrate#typical-workflow https://www.prisma.io/docs/reference/tools-and-interfaces/pr...) when you re-generate your schema, FK relationships names would be reset, and you'd have to go back through and manually re-update them. (think user.favorite_book would be changed to user.book). Jeeze, I wish I could find the video for that. 3) perhaps I just don't have a good enough understanding of that system to think through it's pitfalls. You guys obviously understand which workflows you cover well through /that/ approach to transactions. Might be good to see which sorts of strategies (won't work). For example, what if I want to `flush` my changes, and `rollback` or use a `savepoint` elsewhere. It seems like everything is in the context of one call. Is that correct?
- 2color 6y ago1) Prisma supports two workflows depending on whether you already have an existing database (introspection) or using Prisma Migrate. It sounds based on your description like something that would happen in the introspection workflow which this "re-introspection" feature resolves by retaining name mapping of relation fields. 3) > For example, what if I want to `flush` my changes, and `rollback` or use a `savepoint` elsewhere. That's not possible. > It seems like everything is in the context of one call. Is that correct? Not exactly, as you can batch multiple calls into one transaction guaranteeing that either all get committed or none. (https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/transactions#the-transaction-api https://www.prisma.io/docs/reference/tools-and-interfaces/pr...)
- mdahlstrand 6y agoI went through the same thoughts as you and went straight to knex for my last project. Turns out knex also has bugs and the limitations from having it support all the databases means some really useful features are not available. For my latest project I've gone with pg, writing sql directly, and I'm not looking back. It's so nice not having to write sql through the abstraction layer of knex. Of course if you think you'll swap your database provider down the line, maybe stay with knex. But I really can't see why I'd want to switch away from postgres at a later date.
- nawgz 6y agoHave you looked at Hasura? For some of my latest dev, I've just stopped worrying about writing data plumbing. I have a tool that I can use to update the schema from any arbitrary state to any arbitrary state so long as there are no column modifications, and then Hasura is able to query my entire schema via GraphQL. You also get row, column, & table-level permissions, an easy auth hook, and the promise of schema stitching (which I must admit I haven't used yet, so I don't know if it's easy or performant). I can't really speak to performance, but I think the Hasura guys did their best to use Postgres' internals wherever possible. Try it out! Also, a similar tool is "Xgenecloud", but I didn't like it as much and have only invested time into Hasura.
- xgenecloud 6y agohey, XgeneCloud creator here. How can we improve ? which parts you didn't like
- nawgz 6y agoI don't have great feedback for you, it's just that I downloaded and ran xgenecloud and was exceedingly confused what to do from the UI that it spawned. It didn't seem clear to me how I could get started, and my options were plentiful; I would've been ok to make a new database thru your UI, point your tool at an existing database, or anything else, but I just didn't have a clear path to querying a schema. With Hasura, I could run it with about 2 docker commands and build a schema thru their web UI, use GraphiQL in their web UI to query the schema, and read docs to get a clear path on how I might use this artifact in production. I guess I would just use Hasura if I was you and see what the experience is like vs XgeneCloud, maybe it will show you what I saw.
- olso 6y agoWe are using ts + apollo-server-koa + dataloader (caching) + knex + graphql-codegen + schemats (for types generated from postgres) It works great. We only have issues with gql resolver types, when resolver expects a string, but in reality, resolver can be a function that returns a string This is completely valid export const resolver: Place = { id: ({ id }: GeneratedDb.Place) => toGlobalId(TYPE, String(id)), But typings expect export const resolver: Place = { id: 'xxx',
- agustif 6y agois typeorm really abandoned though? I've been playing with rc3.0.0 recently... I'm having fun using it with GraphQL Modules and TypeGraphQL The docs are pretty decent too!
- dfee 6y agoOh, you must be using `0.3.0-rc.19` not 3.0.0. (https://www.npmjs.com/package/typeorm https://www.npmjs.com/package/typeorm) The one that was released 5 months ago. Look at the velocity of releases, and you'll come to the conclusion many others have. Also, take a look at the pinned issue for the 0.4.0 release (from Dec, 2018), with no updates, here: https://github.com/typeorm/typeorm/issues/3251 https://github.com/typeorm/typeorm/issues/3251 Or, the "future of TypeORM" issue (also from Dec, 2018) here: https://github.com/typeorm/typeorm/issues/3267 https://github.com/typeorm/typeorm/issues/3267 I'm not upset by any of this. That's just the reality of OSS. I really appreciate the foundation TypeORM provided. But, I think it's role will probably be as a sort of "godfather" for the ORM ecosystem in TS rather than a leader – going foward.
- uzername 6y agoTypeORM's velocity and/or lack of a 1.0 release is troubling. I've been trying to push nest recently to gain some consistency vs wild-west express apps, but TypeORM has been the rough spot. I can see the appeal of using something like the pg driver directly, but then there's all that data mapping.
- agustif 6y agoThis is pretty good though > pleerock commented 25 days ago I would like to ask not to spam here. Thank you. If somebody prefer some alternative - try it, maybe it can better fit your needs. Nothing is perfect and there are always set cons and pros from every project you will use. Open source always lack of accountability, and if you are using some tool, try to support it if you can, because any author can end up switching to something else. It's just matter of time, or your support. So, try to support your favorite tools, no matter if thats TypeORM or MicroORM. Thank you for all your suggestions and support. I find many really good suggestions here, but the reason I don't implement them is because right now I'm able to implement only some of them, others would take too much time and efforts to do. But I think it wouldn't take a good effect to only implement some of them. That's why I'm waiting for a right time. I just want to tell you that I already do have enough money to maintain this library for around 6 months without working on something else. So, I still plan to return back to it and put all my efforts to move it forward and apply all suggestions you have provided. I just need some time, because I took a big project under my responsibility and I can't leave until it's finished. Thanks for understanding. Right now I do my best (considering my business and health) to release new TypeORM versions very month or two to keep it updated with the most critical fixe
- invisible 6y agoWhat bugs did you run into with MikroORM? It looks like there are only two open issues that are classified as bugs on their issue tracker (github).
- dfee 6y agoHa. Well, one of 'em was just fixed. https://github.com/mikro-orm/mikro-orm/issues/725 https://github.com/mikro-orm/mikro-orm/issues/725 There's also a known issue where an insert statement with an `undefined` for a field (rather than the lack of a presence) translates to a null (this is actually a `pg` driver situation). https://github.com/mikro-orm/mikro-orm/issues/719 https://github.com/mikro-orm/mikro-orm/issues/719 Finally, the docs have entities which use TypeScript's `optional` indicator (e.g. `image?: string`). Problem is, that reflects the state of an entity pre-creation. After creation it's going to be `null`, which will definitely escape the type system (you've got strict null checks on in TS, right?). However, typing that same column as `image: string | null` actually produces a `columnType` of JSONB(?) rather than `STRING NULL`. That's a couple examples, but yeah. I invested some heavy hours into the codebase this weekend.
- chansiky 6y agoI remember resorting to using typeorm's queryrunner.query writing SQL by hand quite a few times. Eventually I figured I'll just get really good at SQL. Haven't tried it but MikroORM has been on my list of tools to try out. Hoping its good.