mormot2-orm
/mormot2-orm
Use when defining TOrm classes, building TOrmModel, mapping fields with attributes, configuring virtual tables, or ORM CRUD. Do NOT use for raw SQL (use mormot2-db) or REST (use mormot2-rest-soa).
- Author
- flydev-fr ↗
- Repository
- mormot2-superpowers ↗
- Licence
- MIT
- Last repository change
- 13.06.2026
Assessment and security
- Files in this package
- 5
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 13.06.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
Use when defining TOrm classes, building TOrmModel, mapping fields with attributes, configuring virtual tables, or ORM CRUD. Do NOT use for raw SQL (use mormot2-db) or REST (use mormot2-rest-soa).
Original author description
Use when defining TOrm classes, building TOrmModel, mapping fields with attributes, configuring virtual tables, or ORM CRUD. Do NOT use for raw SQL (use mormot2-db) or REST (use mormot2-rest-soa).
How it works
- When to use
- When NOT to use
- Core idioms
- Common pitfalls
- See also
SKILL.md preview
---
name: mormot2-orm
description: Use when defining TOrm classes, building TOrmModel, mapping fields with attributes, configuring virtual tables, or ORM CRUD. Do NOT use for raw SQL (use mormot2-db) or REST (use mormot2-rest-soa).
---
# mormot2-orm
mORMot 2 ORM layer: declarative `TOrm` classes, `TOrmModel` schema definition, field attribute mapping, virtual tables, and CRUD/batch operations through `TRest` descendants. This skill is authoritative for the `mormot.orm.*` namespace and assumes the conventions defined in `mormot2-core` (RawUtf8 strings, custom RTTI, layered uses). Sibling skills extend this layer: `mormot2-rest-soa` exposes models over HTTP/REST, `mormot2-db` handles raw SQL when the ORM is the wrong tool.
## When to use
- Defining a `TOrm` descendant with typed published properties.
- Building a `TOrmModel` from a list of `TOrm` classes (single or multi-database).
- Mapping field attributes (`stored AS_UNIQUE`, `index N`, `width M`, `default`).
- Configuring virtual tables (`TOrmVirtualTableJson`, `TOrmVirtualTableCsv`, `TOrmVirtualTableExternal`).
- ORM CRUD via `TRest.Add`, `TRest.Update`, `TRest.Retrieve`, `TRest.Delete`.
- Batch operations via `TRestBatch` (insert/update/delete sequences with one round-trip commit).
## When NOT to use
- Raw SQL queries, joins, or custom DDL. Use **mormot2-db**.
- Exposing the ORM as REST endpoints, interface-based services, or SOA contracts. Use **mormot2-rest-soa**.
- Authentication, sessions, JWT, password hashing. Use **mormot2-auth-security** for the crypto, **mormot2-rest-soa** for the REST session lifecycle.
- Foundational types (`RawUtf8`, `TDocVariant`), unit ordering, custom record RTTI. Use **mormot2-core**.
## Core idioms
### 1. Defining a TOrm class
Every persisted field is a `published` property with a mORMot-friendly type. RowID is implicit; do not declare it.
```pascal
uses
mormot.core.base,
mormot.orm.core;
type
TOrmUser = class(TOrm)
private
fEmail: RawUtf8;
fRole: RawUtf8;
fLogon: TDateTime;
published
property Email: RawUtf8 read fEmail write fEmail;
property Role: RawUtf8 read fRole write fRole;
property Logon: TDateTime read fLogon write fLogon;
end;
```
### 2. Building a TOrmModel
A model is the schema. Pass it to the `TRest` (server or client). Free it during shutdown after the `TRest` is gone.
```pascal
uses
mormot.orm.core;
var
Model: TOrmModel;
begin
Model := TOrmModel.Create([TOrmUser, TOrmRole, TOrmAuditLog]);
try
// pass Model to TRestServerDB.Create / TRestClientDB.Create
finally
Model.Free; // after the TRest is destroyed
end;
end;
```
### 3. Unique index and width attributes
`stored AS_UNIQUE` adds a SQL UNIQUE constraint; `index N` sets max length for `RawUtf8` (SQL `VARCHAR(N)`). Both are declarative and read by the ORM at model-creation time.
```pascal
type
TOrmUser = class(TOrm)
published
property Email: RawUtf8 index 120 read fEmail write fEmail
stored AS_UNIQUE; // SQL: VARCHAR(120) UNIQUE NOT NULL
property Slug: RawUtf8 index 64 read fSlug write fSlug;
end;
```
### 4. Registering a virtual table
A virtual table maps a `TOrm` class to a non-SQLite backend (JSON file, CSV, external SQL connection). Register it on the model before opening the database.
```pascal
uses
mormot.orm.core,
mormot.orm.storage;
var
Model: TOrmModel;
begin
Model := TOrmModel.Create([TOrmCsvRow]);
Model.VirtualTableRegister(TOrmCsvRow, TOrmVirtualTableJson); // or Csv / External
// ORM verbs (Retrieve, RetrieveListJson, Add) work transparently against the backend.
end;
```
### 5. Batch insert with commit at end
`TRestBatch` queues operations and ships them in a single round trip. Use it for bulk imports, scheduled syncs, or any path that touches many rows.
```pascal
uses
mormot.orm.core;
var
Batch: TRestBatch;
User: TOrmUser;
i: Integer;
begin
Batch := TRestBatch.Create(Server.Orm, TOrmUser, 1000);
try
User := TOrmUser.Create;
try
for i := 0 to High(Inputs) do
begin
User.Email := Inputs[i].Email;
User.Role := 'member';
Batch.Add(User, true);
end;
finally
User.Free;
end;
Server.Orm.BatchSend(Batch); // single commit
finally
Batch.Free;
end;
end;
```
## Common pitfalls
- **Forgetting the `published` modifier.** Properties under `public` or `private` are invisible to RTTI and the ORM ignores them silently. Symptom: column missing from generated SQL, no error.
- **Naming a field after a SQL reserved word.** A property called `Group`, `Order`, `User`, or `Index` may compile but blow up at first SELECT. Either rename the Pascal property or alias the SQL name.
- **Modifying `TOrm.ID` directly.** The ORM owns `RowID`. Set it only via `Add` (which assigns the new ID back) or `Retrieve` (which reads it). Never declare a `published property ID` either; `TOrm` already exposes it.
- **Using `string` for persisted text fields.** Switch to `RawUtf8`. `string` will compile but every read/write pays a UTF-16 round trip, and JSON serialization may corrupt non-ASCII. See `mormot2-core` for the RawUtf8 boundary rule.
- **Leaking the model on shutdown.** `TOrmModel` is owned by your code, not by the `TRest`. After `Server.Free`, call `Model.Free`. Free in the wrong order and you double-free or leak RTTI structures.
- **Calling `Add` with `SendData=false` then expecting the row to come back.** `SendData` controls whether non-default fields are written. With `false` you get an empty row plus the new ID, not the values you set on the instance.
## See also
- `$MORMOT2_DOC_PATH/mORMot2-SAD-Chapter-05.md` - TOrm and TOrmModel
- `$MORMOT2_DOC_PATH/mORMot2-SAD-Chapter-06.md` - ORM Daily Patterns
- `references/torm-cheatsheet.md`
- `references/torm-model-patterns.md`
- `references/virtual-tables.md`
- `mormot2-core` for RawUtf8 conventions and custom record RTTI
- `mormot2-db` for non-ORM SQL access
- `mormot2-rest-soa` for exposing the ORM as REST
Files in this package (5)
- SKILL.md 6 KB
- eval.md 1 KB
- references/torm-cheatsheet.md 4 KB
- references/torm-model-patterns.md 3 KB
- references/virtual-tables.md 4 KB
Versions
The database has no other skills named mormot2-orm.
Database snapshot: 13.11.2026 · package version fc34abbbc282 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100mormot2-rest-soa
Use when building REST servers/clients, method-based services, or interface-based SOA in mORMot 2. Do NOT use for HTTP transport (use mormot2-net) or auth (use mormot2-auth-security). - 100generating-orm-code
Execute use when you need to work with ORM code generation. This skill provides ORM model and code generation with comprehensive guidance and automation. Trigger with phrases like "generate ORM models", "create entity classes", or "scaffold database models". - 100generating-orm-code
Execute use when you need to work with ORM code generation. This skill provides ORM model and code generation with comprehensive guidance and automation. Trigger with phrases like "generate ORM models", "create entity classes", or "scaffold database models". - 100mormot2-db
Use for raw SQL via TSqlDB* providers, picking DB engines (SQLite, PostgreSQL, MSSQL, Oracle, Mongo, ZEOS, ODBC), pooling, BSON. Do NOT use for ORM (mormot2-orm) or REST (mormot2-rest-soa). - 100drizzle-orm-sql-first-schema
Use this skill when defining lightweight, zero-overhead relational schemas and executing queries with Drizzle ORM. - 100add-sql-fields
TRIGGER when user asks to add fields, properties, or columns to a SQL CRUD microservice's object.