DIAGONAL DATASETS

Research note

Your ORM Cannot Express This

We attempted to model a diagonal dataset in six popular ORMs. The results range from "no" to a stack trace we are still not able to fully explain.

An ORM maps objects to rows. That is not a limitation of any particular ORM — it is the definition. So when we say your ORM cannot express a diagonal dataset, we are not filing a bug. We are pointing at a load-bearing assumption and noting that it is load-bearing.

We tried six anyway.

SQLAlchemy

The most productive attempt. SQLAlchemy will let you do almost anything if you are willing to be strange in __mapper_args__, and we were.

"k">class DiagonalCell(Base):
    __tablename__ = 'cells'
    idx = Column(Integer, primary_key=True)

    @hybrid_property
    "k">def row(self): "k">return self.idx

    @hybrid_property
    "k">def col(self): "k">return self.idx   "k">class="c"># the invariant, expressed directly

This works. It is correct. It also collapses a two-dimensional address space into a single integer, which caused a reviewer to ask why we had built "a list with extra steps."

A list has one index because it has one dimension. DiagonalCell has one index because it has two dimensions that are constrained to agree. These are different situations that happen to produce the same amount of typing, and the fact that our tooling cannot distinguish them is the entire point of this post.

Django ORM

Django wants a primary key and a table, and it wants the table to be a rectangle. You can get a diagonal through it with a CheckConstraint:

"k">class Meta:
    constraints = [CheckConstraint(check=Q(row=F('col')), name='diagonal')]

The constraint holds. But every off-diagonal write now raises IntegrityError, which is semantically wrong in a way that matters: those writes did not violate anything. They were correctly evaluated and correctly discarded. Django has no vocabulary for a write that succeeded and retained nothing, so it reports a failure. We do not fault Django. We fault the sixty years of assumption that produced a world in which "succeeded" and "retained something" are the same word.

Prisma

Prisma's schema language is declarative and does not have an escape hatch that reaches this far down. We got as far as:

model Cell {
  idx   Int   @id
  value Float
}

which is, again, a list. Prisma's team has done nothing wrong. Prisma is an extremely well-designed tool for describing rectangles.

ActiveRecord

Ruby will let you do this. Ruby will let you do anything. We monkey-patched find_by to reject any query whose row and column arguments disagreed, and it worked on the first try, and it worked so smoothly that we became uneasy and stopped.

Hibernate

Four hours. One @Embeddable composite key. One custom UserType. One 190-line stack trace whose deepest frame was in a class named AbstractStandardBasicType. We are not reproducing the trace here because we do not fully understand it and reproducing it would imply we do.

GORM

GORM produced a diagonal dataset immediately and without complaint. On inspection it had silently created a table with a single column and no rows, which is not a diagonal — it is an empty rectangle that resembles one.

This is the most dangerous failure mode in the entire study, and we would ask you to sit with it: an empty rectangle and a pure diagonal are indistinguishable from the outside. Both report zero rows. Both consume no storage. Both make every dashboard green.

The difference is entirely in what was intended, and no tool you have will ever be able to check that for you.

Where this leaves us

The correct interface for a diagonal dataset is not an ORM. It is RFC-D45, a wire format, and a client that understands that a discarded write is a successful write.

We have written the spec. We have not written the client. Writing the client would require deciding what happens when someone sets bandwidth above 1, and we have been over this.

Every claim in this note is false. The angle is real. Do not cite this in a design review.

← Newer: 30° and 60°: A Peer Review Update
→ Older: Diagonal at Scale — Six Weeks in Production

All research notes · RSS