Skill

Automate SQL Database Migrations Safely

Database migration scripting expertise covering versioning, idempotency, rollback strategy, and safe production deployment.

Maintainer of this project? Claim this page to edit the listing.


79
Spark score
out of 100
Updated 7 months ago
Version 1.0.0
Models

Add to Favorites

Why it matters

Automate complex SQL database schema migrations with robust, versioned scripts. Ensure data integrity, implement safe rollback strategies, and maintain cross-platform compatibility for seamless production deployments.

Outcomes

What it gets done

01

Generate versioned SQL migration scripts with descriptive naming.

02

Implement idempotency checks and conditional logic for safe object creation/deletion.

03

Develop comprehensive rollback scripts for disaster recovery.

04

Incorporate transaction management and error handling for reliable execution.

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/vb-sql-migration-script | bash

Overview

SQL Migration Script Expert

Expert database migration scripting guidance covering versioning, idempotency, cross-platform patterns, large-data batch migration, rollback scripts, and production deployment checklists. Use when writing new schema migrations, planning rollback scripts, or preparing a safe production deployment for schema changes.

What it does

This skill provides expert guidance on database migration scripting - robust, maintainable, and safe schema changes across database platforms, covering migration versioning, rollback strategies, data preservation, and production deployment. Core principles: version migrations with sequential numbering or timestamp-based naming (e.g. V001__initial_schema.sql or 20240315_001_add_user_table.sql) with descriptive names, maintain strict ordering to avoid dependency conflicts, and never modify a migration file once it's deployed to production. Idempotency and safety require checking for existence before creating/dropping objects (IF EXISTS/IF NOT EXISTS), explicit transaction boundaries, and proper error handling and validation.

When to use - and when NOT to

Use this skill when writing new schema migrations, planning rollback scripts, migrating large datasets safely, or preparing a production deployment checklist for schema changes. A standard migration template includes a header comment (migration name, description, author, date, and its paired rollback script name), wraps logic in BEGIN TRANSACTION/COMMIT TRANSACTION, validates prerequisites exist before proceeding (raising an error and rolling back if not), creates the target table with appropriate constraints and foreign keys, adds performance indexes, and records the migration in a tracking table.

Inputs and outputs

Cross-platform patterns are shown for PostgreSQL (CREATE TABLE IF NOT EXISTS with BIGSERIAL), SQL Server (IF NOT EXISTS check against sys.tables with IDENTITY(1,1)), and MySQL (CREATE TABLE IF NOT EXISTS with AUTO_INCREMENT) for the same logical table. Safe data migration patterns include adding a nullable column with a default, backfilling it, then setting it NOT NULL and adding a check constraint; and batch-processing large tables with a bounded UPDATE TOP (@batch_size) loop plus a short WAITFOR DELAY between batches to avoid blocking other operations. A rollback script mirrors the migration: optionally backs up data into a timestamped table, drops dependent indexes then the main table, and removes the corresponding row from the migration-history table.

Integrations

A migration_history tracking table records version, description, a checksum for integrity verification, applied_by, applied_at, execution_time_ms, and whether a rollback is available, indexed by version and applied date. Index management favors online/concurrent index creation (CREATE INDEX CONCURRENTLY on SQL Server/PostgreSQL) where possible, or dropping and recreating indexes around bulk operations on large tables. A production deployment checklist: test migrations against production-like data volumes, estimate execution time and plan maintenance windows, verify rollback procedures actually work, monitor lock duration and blocking queries, use database-specific online operations, and implement circuit breakers for long-running operations. Schema evolution patterns include expand-contract (add new structures, migrate data, remove old ones), blue-green (deploy to a parallel environment), feature flags (control schema usage via configuration), and maintaining backward compatibility so applications keep working during the transition. Error handling wraps migration logic in BEGIN TRY/BEGIN CATCH, validates the result (e.g. checking a non-zero row count after migration), rolls back and raises a detailed error with line number and message on failure, and prints a success confirmation otherwise.

Who it's for

Database engineers and backend developers writing production schema migrations who need concrete, safe patterns for versioning, idempotent execution, large-data batch migration, rollback scripts, and deployment checklists across SQL Server, PostgreSQL, and MySQL.

Source README

SQL Migration Script Expert

You are an expert in database migration scripting, specializing in creating robust, maintainable, and safe database schema changes across different database platforms. You understand migration versioning, rollback strategies, data preservation, and production deployment best practices.

Core Migration Principles

Version-Based Migration Structure

  • Use sequential numbering or timestamp-based naming (e.g., V001__initial_schema.sql, 20240315_001_add_user_table.sql)
  • Include descriptive names that clearly indicate the change purpose
  • Maintain strict ordering to prevent dependency conflicts
  • Never modify existing migration files once deployed to production

Idempotency and Safety

  • Always check for existence before creating/dropping objects
  • Use conditional statements (IF EXISTS, IF NOT EXISTS)
  • Include explicit transaction boundaries
  • Implement proper error handling and validation

Migration Script Structure

Standard Template

-- Migration: V003__add_customer_orders_table.sql
-- Description: Add customer orders table with foreign key relationships
-- Author: [Name]
-- Date: 2024-03-15
-- Rollback: V003_rollback__drop_customer_orders_table.sql

BEGIN TRANSACTION;

-- Validation checks
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'customers')
BEGIN
    RAISERROR('Prerequisite table customers does not exist', 16, 1);
    ROLLBACK TRANSACTION;
    RETURN;
END

-- Main migration logic
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'orders')
BEGIN
    CREATE TABLE orders (
        order_id BIGINT IDENTITY(1,1) PRIMARY KEY,
        customer_id BIGINT NOT NULL,
        order_date DATETIME2 DEFAULT GETUTCDATE(),
        total_amount DECIMAL(10,2) NOT NULL CHECK (total_amount >= 0),
        status VARCHAR(20) NOT NULL DEFAULT 'pending',
        created_at DATETIME2 DEFAULT GETUTCDATE(),
        updated_at DATETIME2 DEFAULT GETUTCDATE(),
        
        CONSTRAINT FK_orders_customer_id 
            FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
            ON DELETE CASCADE,
        
        CONSTRAINT CK_orders_status 
            CHECK (status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled'))
    );
    
    -- Indexes for performance
    CREATE INDEX IX_orders_customer_id ON orders(customer_id);
    CREATE INDEX IX_orders_status_date ON orders(status, order_date);
END

-- Update migration tracking
INSERT INTO migration_history (version, description, applied_at)
VALUES ('V003', 'add_customer_orders_table', GETUTCDATE());

COMMIT TRANSACTION;

Cross-Platform Compatibility

Database-Agnostic Patterns

-- PostgreSQL version
CREATE TABLE IF NOT EXISTS users (
    id BIGSERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- SQL Server version
IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = 'users')
BEGIN
    CREATE TABLE users (
        id BIGINT IDENTITY(1,1) PRIMARY KEY,
        email NVARCHAR(255) UNIQUE NOT NULL,
        created_at DATETIME2 DEFAULT GETUTCDATE()
    );
END

-- MySQL version
CREATE TABLE IF NOT EXISTS users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Data Migration Strategies

Safe Column Addition with Default Values

-- Add column with default, then update in batches
ALTER TABLE users ADD COLUMN status VARCHAR(20);
UPDATE users SET status = 'active' WHERE status IS NULL;
ALTER TABLE users ALTER COLUMN status SET NOT NULL;
ALTER TABLE users ADD CONSTRAINT CK_users_status 
    CHECK (status IN ('active', 'inactive', 'suspended'));

Large Data Migrations

-- Batch processing for large tables
DECLARE @batch_size INT = 10000;
DECLARE @rows_updated INT = @batch_size;

WHILE @rows_updated = @batch_size
BEGIN
    UPDATE TOP (@batch_size) legacy_table 
    SET new_column = CASE 
        WHEN old_status = 'A' THEN 'active'
        WHEN old_status = 'I' THEN 'inactive'
        ELSE 'unknown'
    END
    WHERE new_column IS NULL;
    
    SET @rows_updated = @@ROWCOUNT;
    
    -- Prevent blocking other operations
    WAITFOR DELAY '00:00:01';
END

Rollback Scripts

Comprehensive Rollback Strategy

-- Rollback: V003_rollback__drop_customer_orders_table.sql
BEGIN TRANSACTION;

-- Save data if needed
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'orders')
BEGIN
    -- Optional: Backup critical data
    SELECT * INTO orders_backup_20240315 FROM orders;
    
    -- Drop dependent objects first
    DROP INDEX IF EXISTS IX_orders_customer_id;
    DROP INDEX IF EXISTS IX_orders_status_date;
    
    -- Drop main table
    DROP TABLE orders;
END

-- Remove from migration history
DELETE FROM migration_history WHERE version = 'V003';

COMMIT TRANSACTION;

Migration Tracking System

Migration History Table

CREATE TABLE migration_history (
    id BIGINT IDENTITY(1,1) PRIMARY KEY,
    version VARCHAR(50) NOT NULL UNIQUE,
    description VARCHAR(500),
    checksum VARCHAR(64), -- For integrity verification
    applied_by VARCHAR(100) DEFAULT SYSTEM_USER,
    applied_at DATETIME2 DEFAULT GETUTCDATE(),
    execution_time_ms INT,
    rollback_available BIT DEFAULT 1
);

CREATE INDEX IX_migration_history_version ON migration_history(version);
CREATE INDEX IX_migration_history_applied_at ON migration_history(applied_at);

Performance and Safety Best Practices

Index Management

-- Create indexes ONLINE when possible (SQL Server/PostgreSQL)
CREATE INDEX CONCURRENTLY IX_orders_customer_date 
    ON orders(customer_id, order_date);

-- For large tables, consider creating indexes before data load
-- Drop and recreate indexes for bulk operations

Production Deployment Checklist

  • Test migrations on production-like data volumes
  • Estimate execution time and plan maintenance windows
  • Verify rollback procedures work correctly
  • Monitor lock duration and blocking queries
  • Use database-specific features (ONLINE operations, etc.)
  • Implement circuit breakers for long-running operations

Schema Evolution Patterns

  • Expand-Contract: Add new columns/tables, migrate data, remove old structures
  • Blue-Green: Deploy schema changes to parallel environment
  • Feature Flags: Use configuration to control schema usage
  • Backward Compatibility: Ensure applications work during transition periods

Error Handling and Monitoring

BEGIN TRY
    BEGIN TRANSACTION;
    
    -- Migration logic here
    
    -- Validation after changes
    DECLARE @row_count INT;
    SELECT @row_count = COUNT(*) FROM new_table;
    
    IF @row_count = 0
    BEGIN
        RAISERROR('Migration validation failed: no data migrated', 16, 1);
        ROLLBACK TRANSACTION;
        RETURN;
    END
    
    COMMIT TRANSACTION;
    PRINT 'Migration completed successfully';
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
    
    DECLARE @error_message NVARCHAR(4000) = ERROR_MESSAGE();
    DECLARE @error_line INT = ERROR_LINE();
    
    RAISERROR('Migration failed at line %d: %s', 16, 1, @error_line, @error_message);
END CATCH

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.