The codegen pipeline
What it is
Section titled “What it is”dart run gisila_orm:generate is a single command that turns your schema files
into everything the runtime needs. It writes three kinds of output, and it’s
worth knowing which is which:
| Output | Example | Role | Edit it? |
|---|---|---|---|
| Dart bundle | lib/models/blog.gisila.g.dart |
Models, <Model>Table, relations, query accessors |
Never; regenerated each run |
| Full-schema SQL | blog.gisila.up.sql, .down.sql |
CREATE / DROP of the whole current schema |
Never; regenerated each run |
| Snapshot | .gisila/schema_snapshots/project.gisila.yaml |
The schema as of the last run, used for diffing | Never; commit it |
| Migrations | lib/models/migrations/<millis>_initial_schema.up.sql, <millis>_auto_project_changes.up.sql |
What migrate up applies |
Review before applying; never after |
When to use it
Section titled “When to use it”- After every edit to a
*.gisila.yamlfile. Commit the results together with the YAML. - In CI, run it and fail if
git statusshows changes, to catch a schema edited without regenerating.
When not to use it
Section titled “When not to use it”- To apply changes to a database.
generatenever connects to one; that’smigrate up. - With
build_runnerfor multi-file schemas: the builder does nothing there. See build.yaml.
How it works
Section titled “How it works”lib/**/*.gisila.yaml ─┐test/**/*.gisila.yaml ├─▶ discover ─▶ merge + validate ─▶ emit Dart + full SQLexample/**/… ┘ │ ▼ .gisila/…/project.gisila.yaml (previous snapshot) │ diff (SchemaDiffer) ▼ migrations/<millis>_auto_project_changes.{up,down}.sql │ ▼ snapshot updated- Discover schema files under
lib/,test/andexample/, sorted by path. - Merge and validate. Enums and model names are collected across all files first, so a model in
post.gisila.yamlcan referenceAuthorinauthor.gisila.yaml. Any error stops the run before writing. - Emit the bundle. With one schema file, beside it using its stem; with several, as
lib/models/schema.gisila.*. - Bootstrap migrations. If you have no migrations yet, write
<millis>_initial_schemaso a fresh database can be built from migrations alone. - Diff. Compare the current schema with the snapshot. If they differ, write
<millis>_auto_project_changes. If the change would lose data, write nothing, leave the snapshot alone and exit with an error until you re-run with--allow-destructive. - Update the snapshot.
Why the snapshot matters
Section titled “Why the snapshot matters”Incremental migrations are diffs between the snapshot and the current schema.
The snapshot must be committed and shared: if a teammate’s checkout has no
snapshot, their first run only records one and writes no migration, and the
change you expected to see is lost. If two branches both change the schema,
each generates its own migration; after merging, run generate again and check
that the combined result is right.
Full SQL versus migrations
Section titled “Full SQL versus migrations”*.gisila.up.sql always describes the whole current schema, so you can’t use
it to upgrade an existing database. migrate skips these files when the
directory also contains real migrations, and only falls back to them when
there is nothing else (projects that never ran generate).
Dart output
Section titled “Dart output”The emitted Dart depends only on package:gisila_orm/gisila.dart. It’s
formatted with dart_style and contains no reflection; every model knows how
to build itself from a row (fromRow) and turn itself back into one (toRow).
Example
Section titled “Example”A schema change and what it produces:
# lib/models/blog.gisila.yaml - add a column to Post slug: { type: varchar, is_null: true, is_unique: true }$ dart run gisila_orm:generateGenerated 1 schema file(s) → lib/models/blog.gisila.g.dart, lib/models/blog.gisila.up.sqlGenerated migration files: Up: lib/models/migrations/1730460000000_auto_project_changes.up.sql Down: lib/models/migrations/1730460000000_auto_project_changes.down.sqlAuto incremental migration generated: auto_project_changes-- Migration: auto_project_changes-- Generated on: 2026-11-01T10:00:00.000
BEGIN;
-- Add column: posts.slugALTER TABLE "posts" ADD COLUMN "slug" VARCHAR(255) UNIQUE;
COMMIT;