Skip to content

Why Mabat

Mabat is not an ORM in the Hibernate sense, and not a query builder. It sits between them: you declare the shape of the data a use case reads — an aggregate — and Mabat owns the queries that fill it.

MabatDiesel / SeaORMHand-written SQLx
Nested aggregates in one callDeclared once, loaded with one batched query per relationshipAssembled by hand from several queries, or joins that duplicate rowsAssembled by hand
Enums with data (sum types)Native: tag column or table per variant, strict decodingNot supported; flatten into columnsBy hand
Recursive trees and cyclic graphsdepth, WITH RECURSIVE, Ref<T> graphs, no Rc/RefCellBy handBy hand
Tuning a query in productionOverride file, checked at startup, shadow-compared, hot-reloadedChange code and redeployChange code and redeploy
JSON and GraphQL from the same viewsSelections and a generated schemaSeparate layerSeparate layer
Writing backWhole aggregates, or only what changed, with version lockingRow by rowRow by row
  • Read-heavy services whose responses are nested documents: an API’s detail pages, a GraphQL backend, exports.
  • Teams where DBAs tune SQL: overrides let them change a query without a Rust release, and the startup checks make sure a change matches the code.
  • Domains with sum types and trees, which relational ORMs flatten.
  • Ad-hoc analytical queries: write them with SQLx directly; Mabat composes with it on the same connection.
  • Schema management: Mabat reads existing tables and does not generate or migrate schemas (MPA-NOT-9).
  • Workloads that save large graphs often: save_graph writes every entity, not only the changed ones (MPA-NOT-10).