What this article misses IMO is a clear distinction of the various abstractions layers an ORM can provide, most importantly these two:

- Heavy ORMs: Object-oriented mapping layers that map classes to tables. A record is represented as an object that not only carries data but also implements various behaviours for storage, retrieval, serialization and deserialization of its own data, sometimes it also implements business/domain logic. Examples: ActiveRecord, EntityFramework, Hibernate, Sequelize, ...

- Lightweight query builders: Lightweight, programmatic abstractions on top of SQL. Examples: knex.js, pypika, ...

There are issues with both approaches.

Heavy ORMs

Heavy ORMs make it seem like a developer doesn't need to know SQL to work with a database. They help to get a project off the ground quickly, but as a project grows and requirements become more complex, they often generate slow queries or generally lack capabilities to express the right queries. After all, a developer will be forced to understand what's going on in the SQL layer underneath, spending a lot of time debugging and understanding the generated queries, often without the possibility to optimize them. The premise of "not knowing SQL" and productively working with database longterm has just been proven wrong in so many cases (I feel like everyone has been burnt by an ORM at least once in their dev career...).

Lightweight query builders

Lightweight query builders on the other hand don't try to abstract too much away from SQL. Their APIs typically use SQL terminology and they're not trying to hide the fact that they're working with a database. Coming from an application developers perspective, there still is the drawback that you must have a solid understanding of SQL to work with them efficiently. Another issue that these query builder APIs typically aren't type-safe. There's no static analysis that can help identify typos or other issues in the DB queries you're building. In terms of developer experience, they lack features like autocompletion for DB queries. Personally, I still prefer query builders over heave ORMs since I get more control.

Time for a plug: I work at Prisma where our mission is to make it easier for application developers to work with databases by providing developer-friendly, efficient and performant abstractions and tools for working with database! We're currently building the Prisma Framework [1] which consists of two main tools:

- Photon [2]: A lightweight, auto-generated and type-safe database client

- Lift [3]: A tool for declarative data modeling and database migrations

You can learn more about both tools in this blog post: https://www.prisma.io/blog/announcing-prisma-2-zq1s745db8i5/

Both tools are based on the Prisma schema [4], a declarative abstraction over your database schema that serves as foundation for the generated Photon API. Lift migrations work by mapping the Prisma schema to your database schema. We also build a ton of other nice tools and libraries that simplify database workflows (such as Prisma Studio, a database GUI) or integrations with API layers, such as GraphQL Nexus [5] for building type-safe GraphQL APIs without boilerplate.

To get started, check out this tutorial: https://github.com/prisma/prisma2/blob/master/docs/tutorial....

[1] https://github.com/prisma/prisma2

[2] https://photonjs.prisma.io/

[3] https://lift.prisma.io/

[4] https://github.com/prisma/prisma2/blob/master/docs/prisma-sc...

[5] https://github.com/prisma/nexus