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.
1.0.0Add 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
Generate versioned SQL migration scripts with descriptive naming.
Implement idempotency checks and conditional logic for safe object creation/deletion.
Develop comprehensive rollback scripts for disaster recovery.
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.