Skip to content

Migration Workflow — Complete Guide

DodaTech Updated 2026-06-28 7 min read

In this tutorial, you will learn about Migration Workflow. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn migration workflow: best practices for creating, reviewing, testing, and deploying database migrations. Structure migration development for team collaboration and safe production deployments.

What You Learn

You will learn a complete migration workflow: how to create migrations during development, review them in pull requests, test them in CI/CD, deploy them safely to production, and handle failures or rollbacks.

Why It Matters

A structured migration workflow prevents production incidents. Teams that follow a workflow catch issues before deployment, avoid schema drift, and can rollback safely. Teams without a workflow cause downtime and data loss.

Real-World Use

DodaTech's migration workflow has four stages: development (create and test locally), review (PR with schema diff), CI (test against staging copy), and deploy (automated with rollback plan). This workflow prevented 12 production incidents in the last year.

Development Phase

# 1. Create a feature branch
git checkout -b feat/add-phone-to-users

# 2. Make changes to models/schema
# (Modify SQLAlchemy models, Django models, schema.prisma, etc.)

# 3. Generate the migration
# Alembic:
alembic revision --autogenerate -m "add phone to users"

# Django:
python manage.py makemigrations

# Prisma:
npx prisma migrate dev --name add_phone_to_users

# 4. Apply locally and verify
alembic upgrade head
python manage.py migrate
npx prisma migrate deploy

# 5. Test the migration
# - Run the application
# - Verify new features work
# - Test downgrade

Expected output: Migration is created on a feature branch. The developer applies it locally, tests the application, and verifies both upgrade and downgrade work correctly.

Migration Review Checklist

# Migration Review Checklist

## Schema Changes
- [ ] Does the migration add, remove, or rename columns?
- [ ] Are new columns nullable or have defaults?
- [ ] Are removed columns actually unused?
- [ ] Is the column type appropriate (VARCHAR length, DECIMAL precision)?

## Data Safety
- [ ] Does the migration preserve existing data?
- [ ] Are data backfills batched (not one massive UPDATE)?
- [ ] Is there a down migration that restores data?
- [ ] Will the migration lock tables for more than a few seconds?

## Performance
- [ ] Does the migration add indexes for new query patterns?
- [ ] Does the migration remove unused indexes?
- [ ] Will the migration complete within the deployment window?
- [ ] Are there online alternatives for large tables?

## Rollback
- [ ] Is there a tested down migration?
- [ ] Does the down migration restore exact previous state?
- [ ] Is there a communication plan if rollback is needed?

## Code Changes
- [ ] Does application code match the new schema?
- [ ] Are there any references to removed columns?
- [ ] Are environment variables updated for new config?

Expected output: Review checklist ensures all aspects of a migration are reviewed: schema correctness, data safety, performance impact, rollback capability, and code compatibility.

CI/CD Testing

# .github/workflows/migrations.yml
name: Migration Tests

on:
    pull_request:
        paths:
            - 'migrations/**'
            - '**/models/**'
            - 'prisma/schema.prisma'

jobs:
    test-migration:
        runs-on: ubuntu-latest
        services:
            postgres:
                image: postgres:16
                env:
                    POSTGRES_PASSWORD: postgres
                options: >-
                    --health-cmd pg_isready
                    --health-interval 10s
                    --health-timeout 5s
                    --health-retries 5

        steps:
            - uses: actions/checkout@v4

            - name: Set up Python
              uses: actions/setup-python@v5
              with:
                  python-version: '3.12'

            - name: Install dependencies
              run: pip install -r requirements.txt

            - name: Create test database
              run: createdb -h localhost -U postgres test_migrations

            - name: Apply all migrations
              run: alembic upgrade head
              env:
                  DATABASE_URL: postgresql://postgres:postgres@localhost/test_migrations

            - name: Verify schema matches models
              run: python -c "from app import db; db.engine.connect()"

            - name: Test rollback
              run: |
                  alembic downgrade -1
                  alembic upgrade head

Expected output: CI pipeline creates a fresh database, applies all migrations, verifies the application starts, and tests rollback. This catches migration issues before they reach production.

Deploy Phase

# Deployment pipeline
stages:
  - migrate
  - deploy
  - verify

# Stage 1: Run migrations
migrate:
  stage: migrate
  script:
    - alembic upgrade head
  environment: production
  only:
    - main

# Stage 2: Deploy application
deploy:
  stage: deploy
  script:
    - kubectl apply -f deployment.yaml
  environment: production
  needs: ["migrate"]
  only:
    - main

# Stage 3: Verify deployment
verify:
  stage: verify
  script:
    - python scripts/verify_schema.py
    - python scripts/run_smoke_tests.py
  environment: production
  needs: ["deploy"]
  only:
    - main

Expected output: Pipeline has three stages: migrate (run schema changes), deploy (update application), verify (run health checks). If migrate fails, deploy is skipped. If verify fails, rollback is triggered.

Rollback Procedure

# scripts/rollback.py - Automated rollback script
import subprocess
import sys
import time

def rollback_migration(steps=1):
    print(f"Rolling back {steps} migration(s)...")

    try:
        # 1. Run rollback
        result = subprocess.run(
            ['alembic', 'downgrade', f'-{steps}'],
            capture_output=True, text=True, check=True
        )
        print("Schema rollback successful")

        # 2. Verify rollback
        result = subprocess.run(
            ['alembic', 'current'],
            capture_output=True, text=True, check=True
        )
        print(f"Current version: {result.stdout.strip()}")

        # 3. Run health checks
        time.sleep(5)
        health_result = subprocess.run(
            ['python', 'scripts/health_check.py'],
            capture_output=True, text=True
        )

        if health_result.returncode == 0:
            print("Health checks passed after rollback")
            return True
        else:
            print(f"Health check failed: {health_result.stderr}")
            return False

    except subprocess.CalledProcessError as e:
        print(f"Rollback failed: {e.stderr}")
        return False

if __name__ == '__main__':
    steps = int(sys.argv[1]) if len(sys.argv) > 1 else 1
    success = rollback_migration(steps)
    sys.exit(0 if success else 1)

Expected output: Rollback script reverts migrations, verifies the current version, and runs health checks. This is used when a deployment is rolled back.

Communication Plan

// migration-communication.js
const migrationPlan = {
    migration: '20260628_add_phone_to_users',
    author: 'developer@example.com',
    reviewer: 'senior@example.com',

    // Timing
    plannedWindow: '2026-06-29 02:00 - 02:30 UTC',
    expectedDuration: '5 minutes',
    riskLevel: 'low', // low, medium, high

    // Schema changes
    changes: [
        {
            type: 'add_column',
            table: 'users',
            column: 'phone',
            details: 'VARCHAR(20), nullable, no default',
        },
    ],

    // Rollback
    rollbackProcedure: 'alembic downgrade -1',
    rollbackDuration: '1 minute',
    rollbackTested: true,

    // Communication
    notify: [
        '#engineering',
        '@backend-team',
        '@on-call',
    ],
};

module.exports = migrationPlan;

Expected output: Migration plan includes timing, changes, rollback procedure, and notification list. This is shared before deployment. Stakeholders know what is changing and what to do if something goes wrong.

Common Mistakes

1. Skipping Migration Review

Migrations merged without review cause production issues. Enforce migration review in pull requests. Use the review checklist. Require senior developer approval for schema changes.

2. Not Testing Rollback

Migrations without tested rollbacks are dangerous. If a migration breaks production, you need a working rollback. Test downgrade in CI. Verify the rollback restores the exact previous schema.

3. Running Migrations Outside Deployment Pipeline

Developers running migrations manually on production bypasses controls. Automate migrations in the deployment pipeline. Disable manual migration execution on production.

4. No Communication About Schema Changes

Teams depending on the database are surprised by schema changes. Communicate planned migrations in advance. Share migration plans during Standup. Document schema changes in release notes.

5. Ignoring Migration Performance

Migrations that lock large tables cause downtime. Check migration performance on a production-size copy. Use online schema change tools for large tables. Schedule long migrations during maintenance Windows.

Practice Questions

1. What are the stages of a migration workflow?

Development (create and test locally), Review (PR with checklist), CI (test against staging), Deploy (automated pipeline), Verify (health checks), and Rollback (if needed).

2. Why should migrations be tested in CI/CD?

CI/CD testing catches issues before production: syntax errors, ordering problems, missing dependencies, and rollback failures. A fresh database in CI ensures clean application of all migrations.

3. What is the purpose of the migration review checklist?

The checklist ensures migration correctness: data safety, performance impact, rollback capability, and code compatibility. It prevents common migration mistakes from reaching production.

4. How do you handle migration failures in production?

Abort the deployment. Do not apply further migrations. Investigate the failure. If fix is quick, create a corrective migration. Otherwise, rollback and fix in development. Communicate status to stakeholders.

Challenge

Create a complete migration workflow for a team: branch naming convention (feat/add-column, fix/migration-fix), migration creation steps, PR template with migration checklist, CI pipeline with fresh database and rollback test, deployment pipeline with migrate-deploy-verify stages, rollback script, and migration communication template.

FAQ

How long should a migration review take?

Simple migrations (add nullable column) should be reviewed within hours. Complex migrations (data transformation, table rename) may take a day. Use the checklist to speed up review.

Who should review migrations?

At least one senior developer familiar with the schema and database. For complex migrations, involve a DBA. For data migrations, involve the data team.

How do I handle emergency migrations?

Emergency migrations follow the same workflow but accelerated. Create the migration, get expedited review, run CI, deploy with monitoring. Document the emergency for post-mortem.

Can I run multiple migrations in one deployment?

Yes. The migration tool applies them in order. Group related migrations in the same deployment. Avoid deploying unrelated migrations together for easier rollback.

What is the best time to run migrations?

During low-traffic periods. For consumer apps, early morning (2-4 AM). For business apps, weekends. Align with the maintenance window. Monitor after migration.

Mini Project: Migration Workflow Automation

Build a migration workflow automation tool that: validates migration naming conventions, generates PR descriptions with schema diff, runs migration tests in CI against a fresh database, deploys migrations with rollback capability, sends Slack notifications for migration status, and generates migration audit reports.

What's Next

Now that you understand migration workflow, learn about Branching and Merging for handling parallel migration development.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro