Migrations

Version control for your database schema

Category: Database

Database Migrations

Migrations are like version control for your database, allowing your team to define and share the application's database schema definition. If you have ever had to tell a teammate to manually add a column to their local database schema, you've faced the problem that database migrations solve.

Running Migrations #

To run all of your outstanding migrations, execute the migrate command:

./velvet migrate

Module Migrations #

You can run migrations for a specific module by providing the path:

./velvet migrate --path=modules/my-module/database/migrations

Migration Structure #

VelvetCMS uses raw SQL files for migrations to ensure maximum compatibility and performance. Migration files are stored in database/migrations (or your module's migration directory).

Files should be named with a numeric prefix to ensure execution order:

  • 001_create_users_table.sql
  • 002_add_role_to_users.sql

Example Migration #

-- 001_create_pages_table.sql

CREATE TABLE IF NOT EXISTS pages (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    slug VARCHAR(255) NOT NULL UNIQUE,
    title VARCHAR(255) NOT NULL,
    content TEXT,
    status VARCHAR(20) DEFAULT 'draft',
    layout VARCHAR(50) DEFAULT 'default',
    excerpt TEXT,
    meta TEXT, -- JSON storage
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    published_at DATETIME
);

CREATE INDEX idx_pages_status ON pages(status);

Creating Migrations #

Currently, you create migration files manually in the database/migrations directory.

  1. Create a new file: database/migrations/00X_description.sql
  2. Write your SQL DDL statements.
  3. Run ./velvet migrate.

Migration History #

VelvetCMS tracks which migrations have been run in the migrations table. This prevents the same migration from running twice.

If you need to refresh your database completely, you can delete the database file (for SQLite) or drop tables manually, then run ./velvet migrate again.