Schema dump

Table of contents
  1. Schema dump
    1. Introduction
    2. Dumping
    3. Loading
    4. Limits

Introduction

After a few hundred migrations, building a fresh database means replaying all of them. schema:dump squashes the history into one SQL file. A database with no migration history loads that file and then runs only the migrations written after it (Laravel’s schema:dump).

The dump is generated by migro itself: it runs every migration in --pretend mode and records the SQL. No pg_dump or mysqldump is needed, and nothing is written to the database.

Dumping

migro schema:dump
# Schema dumped: database/schema/postgres-schema.sql (240 migrations, 612 statements)

The file is named after the dialect (sqlite-schema.sql, postgres-schema.sql, …). Commit it. It lists the squashed migrations in comment lines, followed by plain SQL:

-- migro schema dump
-- dialect: postgres
-- migration: 20260201000001_create_users_table
-- migration: 20260201000002_create_posts_table

CREATE TABLE "users" (...);

Dump from an empty database. A migration that inspects the existing schema (HasTable, …) would otherwise record a different history.

Loading

Nothing to configure: migration:run (and migration:fresh, migration:refresh) picks up database/schema/<dialect>-schema.sql when it exists.

  • On a database with no migration history, it executes the dump, records the squashed migrations as applied in batch 1, then runs the rest.
  • On a database that already has history, the dump is ignored.
  • --pretend shows the dump as one step named schema dump, followed by the migrations that remain.
  • A dump made for another dialect is refused with INVALID_SCHEMA.

From code:

b, _ := os.ReadFile("database/schema/postgres-schema.sql")
dump, err := migrate.ParseDump(string(b))
m := migrate.New(db, migrate.WithDump(dump))

Migrator.Dump(ctx) builds a dump, Dump.String() renders it, and Migrator.LoadDump(ctx, dump) applies one directly.

Limits

  • The dump is tied to one dialect. Dump once per database you deploy to.
  • Squashed migration files can be deleted, but keep them until every environment has migrated past them: migration:rollback cannot undo a migration it no longer has.
  • On databases without transactional DDL (MySQL, MariaDB), a dump that fails halfway leaves the tables it created. Run migration:fresh to start over.
  • Statements that return rows cannot be recorded in pretend mode, so a migration that depends on query results cannot be dumped.