database-migration-helper

Database Migration Helper Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "database-migration-helper" with this command: npx skills add dexploarer/hyper-forge/dexploarer-hyper-forge-database-migration-helper

Database Migration Helper Skill

Expert at creating safe, reversible database migrations across different frameworks and tools.

When to Activate

  • "create database migration for [change]"

  • "generate migration to add [table/column]"

  • "write data migration for [transformation]"

Prisma Migrations

// prisma/schema.prisma model User { id Int @id @default(autoincrement()) email String @unique name String role Role @default(USER) posts Post[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt

@@index([email]) @@map("users") }

model Post { id Int @id @default(autoincrement()) title String slug String @unique content String @db.Text published Boolean @default(false) authorId Int author User @relation(fields: [authorId], references: [id], onDelete: Cascade) publishedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt

@@index([slug]) @@index([authorId, publishedAt]) @@map("posts") }

enum Role { USER ADMIN MODERATOR }

Create migration

npx prisma migrate dev --name add_user_role

Apply migrations

npx prisma migrate deploy

Reset database (development only)

npx prisma migrate reset

Create migration without applying

npx prisma migrate dev --create-only

TypeORM Migrations

// migrations/1234567890-AddUserRole.ts import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';

export class AddUserRole1234567890 implements MigrationInterface { name = 'AddUserRole1234567890';

public async up(queryRunner: QueryRunner): Promise<void> { // Add role column await queryRunner.addColumn( 'users', new TableColumn({ name: 'role', type: 'enum', enum: ['user', 'admin', 'moderator'], default: "'user'", }) );

// Create index
await queryRunner.createIndex(
  'users',
  new Index({
    name: 'IDX_USERS_ROLE',
    columnNames: ['role'],
  })
);

// Data migration - set existing users to 'user' role
await queryRunner.query(
  `UPDATE users SET role = 'user' WHERE role IS NULL`
);

}

public async down(queryRunner: QueryRunner): Promise<void> { // Remove index await queryRunner.dropIndex('users', 'IDX_USERS_ROLE');

// Remove column
await queryRunner.dropColumn('users', 'role');

} }

Generate migration from entity changes

npm run typeorm migration:generate -- -n AddUserRole

Create empty migration

npm run typeorm migration:create -- -n DataMigration

Run migrations

npm run typeorm migration:run

Revert last migration

npm run typeorm migration:revert

Alembic (Python) Migrations

alembic/versions/001_add_user_role.py

"""add user role

Revision ID: 001 Revises: Create Date: 2024-01-01 12:00:00

""" from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql

revision identifiers

revision = '001' down_revision = None branch_labels = None depends_on = None

def upgrade(): # Create enum type role_enum = postgresql.ENUM('user', 'admin', 'moderator', name='role') role_enum.create(op.get_bind())

# Add column
op.add_column(
    'users',
    sa.Column('role', role_enum, nullable=False, server_default='user')
)

# Create index
op.create_index('ix_users_role', 'users', ['role'])

# Data migration
op.execute("""
    UPDATE users
    SET role = 'admin'
    WHERE email IN (SELECT email FROM admin_emails)
""")

def downgrade(): # Remove index op.drop_index('ix_users_role', table_name='users')

# Remove column
op.drop_column('users', 'role')

# Drop enum
op.execute('DROP TYPE role')

Create migration

alembic revision -m "add user role"

Auto-generate migration from models

alembic revision --autogenerate -m "add user role"

Run migrations

alembic upgrade head

Rollback one migration

alembic downgrade -1

Show current version

alembic current

Sequelize Migrations (Node.js)

// migrations/20240101120000-add-user-role.js 'use strict';

module.exports = { up: async (queryInterface, Sequelize) => { // Add column await queryInterface.addColumn('users', 'role', { type: Sequelize.ENUM('user', 'admin', 'moderator'), allowNull: false, defaultValue: 'user', });

// Add index
await queryInterface.addIndex('users', ['role'], {
  name: 'users_role_idx',
});

// Data migration using raw SQL
await queryInterface.sequelize.query(`
  UPDATE users
  SET role = 'admin'
  WHERE is_admin = true
`);

// Remove old column
await queryInterface.removeColumn('users', 'is_admin');

},

down: async (queryInterface, Sequelize) => { // Re-add old column await queryInterface.addColumn('users', 'is_admin', { type: Sequelize.BOOLEAN, defaultValue: false, });

// Reverse data migration
await queryInterface.sequelize.query(`
  UPDATE users
  SET is_admin = true
  WHERE role = 'admin'
`);

// Remove index
await queryInterface.removeIndex('users', 'users_role_idx');

// Remove column and enum
await queryInterface.removeColumn('users', 'role');
await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_users_role"');

}, };

Raw SQL Migration Template

-- Up Migration -- migrations/001_add_user_role_up.sql

-- Add enum type (PostgreSQL) CREATE TYPE user_role AS ENUM ('user', 'admin', 'moderator');

-- Add column ALTER TABLE users ADD COLUMN role user_role NOT NULL DEFAULT 'user';

-- Create index CREATE INDEX idx_users_role ON users(role);

-- Data migration UPDATE users SET role = 'admin' WHERE id IN (1, 2, 3);

-- Down Migration -- migrations/001_add_user_role_down.sql

-- Remove index DROP INDEX IF EXISTS idx_users_role;

-- Remove column ALTER TABLE users DROP COLUMN IF EXISTS role;

-- Drop type DROP TYPE IF EXISTS user_role;

Complex Data Migration Example

// Data transformation migration export class MigrateUserData1234567890 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise<void> { // 1. Create new table structure await queryRunner.query( CREATE TABLE users_new ( id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE NOT NULL, profile JSONB NOT NULL, created_at TIMESTAMP DEFAULT NOW() ) );

// 2. Migrate data with transformation
await queryRunner.query(`
  INSERT INTO users_new (id, email, profile, created_at)
  SELECT
    id,
    email,
    jsonb_build_object(
      'firstName', first_name,
      'lastName', last_name,
      'phone', phone,
      'address', jsonb_build_object(
        'street', address_street,
        'city', address_city,
        'zip', address_zip
      )
    ) as profile,
    created_at
  FROM users_old
`);

// 3. Drop old table
await queryRunner.query(`DROP TABLE users_old`);

// 4. Rename new table
await queryRunner.query(`ALTER TABLE users_new RENAME TO users`);

}

public async down(queryRunner: QueryRunner): Promise<void> { // Reverse migration // ... implementation } }

Best Practices

  • Always include both up and down migrations

  • Test migrations on copy of production data

  • Use transactions for data migrations

  • Add indexes after data insertion for large tables

  • Version control all migrations

  • Never modify existing migrations after deployment

  • Use descriptive migration names

  • Add comments explaining complex migrations

  • Test rollback procedures

  • Back up database before major migrations

  • Use batching for large data migrations

  • Monitor migration execution time

  • Handle NULL values properly

  • Validate data after migration

Output Checklist

  • ✅ Migration file created

  • ✅ Up migration implemented

  • ✅ Down migration implemented

  • ✅ Indexes added

  • ✅ Data migration (if needed)

  • ✅ Constraints added

  • ✅ Tested on sample data

  • 📝 Migration notes documented

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

threejs-scene-builder

No summary provided by upstream source.

Repository SourceNeeds Review
General

deployment-helper

No summary provided by upstream source.

Repository SourceNeeds Review
General

drizzle-migration

No summary provided by upstream source.

Repository SourceNeeds Review
General

api-documentation-generator

No summary provided by upstream source.

Repository SourceNeeds Review