{"title":"Migrations","description":"Create, apply, inspect, roll back, and ship Micrate SQL migrations with Amber V2","section":"guides/models/grant","version":"v2","path":"guides/models/grant/migrations","canonical_url":"https://amberframework.org/docs/v2/guides/models/grant/migrations","markdown_url":"https://amberframework.org/docs/v2/guides/models/grant/migrations.md","inherited":false,"content_markdown":"# Database Migrations\n\nAmber CLI `2.0.6` ships Micrate inside the `amber` executable. A generated web\napplication does not need a second migration binary or a Micrate shard entry.\nMigration files belong under `db/migrations/` and database commands run from\nthe application root.\n\n## Generate a migration\n\n**Run from: the application root beside `shard.yml`.**\n\n```bash\namber generate migration AddBirthdayToPets\n```\n\n**Generated file: `db/migrations/<timestamp>_add_birthday_to_pets.sql`.**\n\n```sql\n-- Migration: add_birthday_to_pets\n-- Created: 2026-08-11 20:00:00 UTC\n\n-- +micrate Up\n-- Add SQL to apply the migration here.\n\n-- +micrate Down\n-- Add SQL to roll the migration back here.\n```\n\nThe timestamp is part of the migration version. Keep it in the filename and\ncommit the file once; do not rename an applied migration.\n\n## Write both directions\n\n**File: `db/migrations/<timestamp>_add_birthday_to_pets.sql` — replace the two\nplaceholder comments.**\n\n```sql\n-- +micrate Up\nALTER TABLE pets ADD COLUMN birthday DATE;\n\n-- +micrate Down\nALTER TABLE pets DROP COLUMN birthday;\n```\n\nWrite SQL for the database selected when the application was generated. SQL\nfeatures differ across SQLite, PostgreSQL, and MySQL; test both directions on\nthe same engine and major version used in production. In particular, older\nSQLite versions support fewer `ALTER TABLE` operations and may require a table\nrebuild migration.\n\n## Apply development and test separately\n\n**Run from: the application root.**\n\n```bash\namber database migrate\nAMBER_ENV=test amber database migrate\n```\n\nThe command reads `config/environments/development.yml` by default and\n`config/environments/test.yml` when `AMBER_ENV=test`. `DATABASE_URL` overrides\nthat file for CLI operations.\n\nFor SQLite, the first migration creates the database file. For PostgreSQL or\nMySQL, create the database first when it does not already exist:\n\n**Run from: the application root for a PostgreSQL or MySQL database.**\n\n```bash\namber database create\namber database migrate\n```\n\n## Inspect and reverse\n\n**Run from: the application root.**\n\n```bash\namber database status\namber database version\namber database rollback\namber database redo\n```\n\n- `status` lists applied and pending files.\n- `version` prints the latest applied migration version.\n- `rollback` runs the latest applied Down section once.\n- `redo` rolls back and reapplies the latest migration.\n\nUse rollback and redo while developing a new migration. Once a migration has\nbeen applied in a shared environment, add a new corrective migration instead\nof rewriting its history.\n\n## Seed data\n\n**File: `db/seeds.cr` — application-owned seed program.**\n\n```crystal\nrequire \"../config/*\"\nrequire \"../src/models/**\"\n\nPet.create(name: \"Miso\", species: \"Cat\", adopted: false)\n```\n\n**Run from: the application root after migrations.**\n\n```bash\namber database seed\n```\n\nKeep production seed behavior idempotent or explicitly one-time. A seed is\nordinary application code; it is not tracked as a migration version.\n\n## Release workflow\n\nBefore deploying an application with schema changes:\n\n1. Back up the production database and prove the restore path.\n2. Apply the migration to a production-shaped staging database.\n3. Run request and model specs against the migrated test database.\n4. Review locks, table rewrites, and compatibility with the currently running\n   application version.\n5. Apply migrations as an explicit release step before starting code that\n   requires the new schema.\n\nThe default SQLite workflow is excellent for local development and small\nsingle-host applications. Choose PostgreSQL or MySQL when the deployment needs\nindependent database scaling, multiple application hosts, or operational\nfeatures provided by those servers."}