An ORM Doesn't Replace the Schema. It Automates It.

What an ORM actually does with the gap between a class diagram and a database schema, why it can read and write in both directions, and why it isn't the right tool for a non-relational database.

September 1, 20262 min read16 / 25

The class diagram is finished. Turning it into a schema by hand follows the same three steps every time.

The Three-Step Algorithm Behind Every Schema

  1. Every class becomes a table.
  2. Every primitive attribute becomes a column in that class's table.
  3. Every non-primitive attribute, every association, gets represented by its cardinality — the exact mapping-class and foreign-key patterns this series has been building up all along.

That's mechanical enough that a piece of software can do it instead of a person. That software is called an ORM.

What a Class Diagram Has That a Database Doesn't

A class diagram deals in objects: classes, attributes, inheritance, association. A database deals in something else entirely: tables, columns, IDs, foreign keys. A database has no concept of an object at all.

That gap looks huge on the surface. But the three steps above prove it isn't: you can turn one into the other using a fixed set of steps, nothing more.

What an ORM Actually Automates

An ORM, an Object-Relational Mapper, sits exactly in that gap. The code above it talks entirely in classes and objects. The layer below it talks entirely in tables and rows. Its whole job is translating between the two, automatically, in both directions.

Writing an object saves a row, using the same three steps already described. Reading a row rebuilds the object, and the ORM writes any joins that takes on its own — a User class holding a list of Movie objects needs a join to fetch them, and the ORM writes that join itself, not you.

Picture a method like userRepository.getUserById(id). You never write the SQL. The ORM turns that one call into the actual query, joins included, and hands back a fully formed object instead of a set of raw rows.

Where an ORM Belongs, and Where It Doesn't

This matches a rule already settled earlier in this series: a framework doesn't add capability, it removes work you'd otherwise do by hand. An ORM is the same idea, applied to one specific job: turning a class diagram into a schema. Hibernate (Java), SQLAlchemy (Python, the same engine Django's own ORM runs on), Sequelize (Node.js), and Exposed (Kotlin) all exist to remove that same hand-written work.

Two boundaries are still worth keeping firm. An ORM should stay limited to saving, reading, and updating data. Real validation belongs in the application layer instead, where you can actually see it and test it.

And an ORM's whole design assumes a relational database underneath it, the name says so directly. Against a non-relational database, an ORM usually isn't the right tool at all. It's usually better to use that database's own client library directly, instead of forcing a relational tool onto a document store.