Quick start: versioned migrations
Start with an empty directory. You will write one reversible migration pair,
seal the directory with ptah.sum, apply the pending migration to SQLite, and
verify both the recorded revision and the live table.
This tutorial does not roll the migration back. Rollback is a separate operational task with its own safety contract.
What you need
Section titled “What you need”- A
ptahbinary on yourPATH. Install Ptah if necessary. - A terminal and about seven minutes.
No database server, Docker, or Go toolchain is required.
Step 1. Create your first migration pair
Section titled “Step 1. Create your first migration pair”Migration filenames begin with an integer version. Use the fixed version below so your output matches this page.
mkdir -p ptah-versioned/migrationscd ptah-versionedcat > migrations/1700000000_create_users.up.sql <<'SQL'CREATE TABLE users ( id INTEGER PRIMARY KEY, email TEXT NOT NULL);SQLcat > migrations/1700000000_create_users.down.sql <<'SQL'DROP TABLE users;SQLNew-Item -ItemType Directory ptah-versioned/migrations | Out-NullSet-Location ptah-versioned@'CREATE TABLE users ( id INTEGER PRIMARY KEY, email TEXT NOT NULL);'@ | Set-Content migrations/1700000000_create_users.up.sql@'DROP TABLE users;'@ | Set-Content migrations/1700000000_create_users.down.sqlThe up file changes the database. The down file describes how to reverse that same version.
Step 2. Seal the directory
Section titled “Step 2. Seal the directory”ptah migrations hash --dir ./migrationsExpected output on standard output:
Wrote ./migrations/ptah.sum2 migration file(s) hashedCommit ptah.sum with the migration files. Later commands refuse a migration
file whose bytes no longer match the seal.
Step 3. Apply the migration
Section titled “Step 3. Apply the migration”ptah migrations up --db-url sqlite://app.db --migrations-dir ./migrationsExpected output includes, on standard output:
Current version: 0Total migrations: 1Pending migrations: 1
✅ Migrations completed successfully!Database is now at version: 1700000000Progress records on standard error include timestamps and correlation IDs, so this page does not copy those volatile fields.
Step 4. Verify the recorded revision
Section titled “Step 4. Verify the recorded revision”ptah migrations status --db-url sqlite://app.db --migrations-dir ./migrationsExpected output includes, on standard output:
Current Version: 1700000000Total Migrations: 1Applied Migrations: 1Pending Migrations: 0Out-of-order Migrations: 0Status: ✅ Database is up to dateThis answer comes from Ptah’s revision table inside app.db.
Step 5. Verify the live schema
Section titled “Step 5. Verify the live schema”ptah db read --db-url sqlite://app.dbExpected output includes, on standard output:
CREATE TABLE "users" ( "id" INTEGER PRIMARY KEY, "email" TEXT NOT NULL);The migration history and the database shape now agree.
Step 6. Clean up
Section titled “Step 6. Clean up”cd ..rm -rf ptah-versionedSet-Location ..Remove-Item -Recurse -Force ptah-versionedNext steps
Section titled “Next steps”- Roll back to an explicit revision.
- Validate integrity and preconditions before a shared deployment.
- Generate migration files from a desired schema.
- Gate migration work in CI.