The model layer ¶
Recorded migrations are Cicadel’s standard schema workflow. GORM handles runtime
queries; it never replaces history with AutoMigrate. The first-party
contrib/migrations module supplies generation, historical state, version
dependencies, execution, verification and recovery. Standard management commands
use this implementation.
Ask your agent ¶
Read https://cicadel.fauzaanu.com/en/dev/topics/migrations/index.md.
Add [model or schema change] through the application's registered Models and
recorded PostgreSQL history. Generate and review SQL, test against a disposable
database, and report the plan before touching an existing production database.
Do not use AutoMigrate or rewrite applied migration files.Standard workflow ¶
startproject includes accounts, formsets, migration commands and typed query
generation. startapp blog creates an app with Models(), MigrationDirectory
and an embedded migration filesystem. Register blog.New() in
project/apps.go, retaining the existing first-party registrations.
Add and register a model in apps/blog/models.go:
package blog
import "github.com/fauzaanu/cicadel"
type Note struct {
ID int64 `gorm:"primaryKey"`
Title string `gorm:"not null"`
}
func (Note) TableName() string { return "blog_notes" }
func Models() []cicadel.Model {
return []cicadel.Model{cicadel.ModelOf[Note]("note", "blog_notes")}
}From the project root:
go run manage.go makemigrations blog --name initial
go run manage.go makemigrations blog --check
go run manage.go generatequeries
DATABASE_URL='postgres://.../app' go run manage.go migrate plan
DATABASE_URL='postgres://.../app' go run manage.go migrate
DATABASE_URL='postgres://.../app' go run manage.go migrate verify
DATABASE_URL='postgres://.../app' go run manage.go showmigrationsGeneration and typed query generation run offline, even if DATABASE_URL points
to an unavailable server. App factories used by InstalledApps(nil) must remain
free of database work. Runtime commands require PostgreSQL. Generation compares
registered models with recorded historical state, never a developer’s database.
Review and commit generated SQL and query files. --check does not write files.
Build the application again after generating SQL so its embedded history is current.
Model names, types and table ownership use the same public ModelOf registry for
migrations and typed queries. Declared tables must agree with GORM’s table names.
Configure pinned cross-app historical references, naming strategies and custom
type mappings in project/migrations.go through management.ModelMigrationOptions.
Explicit rename, removal, conversion and backfill declarations use
makemigrations APP --changes changes.json; see the operation contract.
Core module composition ¶
The migration engine is a core default distributed through an installable Go module. Standard projects already include its management commands. Register models and migration sources through the app contract, and generate package-owned migrations in the package source checkout. Application builds load that recorded history from the embedded filesystem.
Cicadel has no releases. These instructions describe the current development implementation; use the same framework revision for the CLI and application.
Recovery ¶
Management commands load all registered migration sources into one dependency
catalog and use the runner’s shared PostgreSQL lock. Applications must register
every app whose applied history they manage. Use migrate plan --target APP=VERSION
to review a target, then migrate apply --target APP=VERSION --allow-data-loss for
a deliberately reviewed rollback. migrate baseline --reason TEXT verifies an
eligible pre-existing initial schema. Nontransactional index recovery uses
migrate recover --migration APP:VERSION --recovery retry|complete.
Migration history is not a data backup. Unsupported changes fail explicitly; see the supported PostgreSQL operations and acceptance evidence.