Database Migrations (PostgreSQL)

Teaches Claude about best practices for PostgreSQL database schema migrations using Flyway with safe, zero-downtime deployments.

Installation

# Install the plugin
claude plugin install database-migrations-postgres@personio-claude-code-marketplace

What does this plugin do?

This plugin provides comprehensive guidance for implementing PostgreSQL database schema migrations using Flyway. It ensures safe, reliable migrations with minimal downtime by following battle-tested patterns for multi-phase deployments, proper locking strategies, and data classification requirements.

/change-database-schema Skill

Create safe PostgreSQL schema migrations that won't break your production database.

When you need to add tables, columns, indexes, or make schema changes, Claude will:

  • Generate migration files following Flyway conventions
  • Apply proper timeout and locking strategies to prevent long-running locks
  • Split complex changes into multi-phase deployments for zero-downtime
  • Add required data classification comments to all columns
  • Include Row Level Security (RLS) policies for tenant isolation
  • Handle jOOQ exclusions for safe rolling updates

What you need:

  • A PostgreSQL database using Flyway for migrations
  • Knowledge of what schema change you want to make
  • Access to GitHub CLI (for fetching data classification documentation)

Quick Start:

Example usage:

/database-migrations-postgres:change-database-schema  I want to add a new column `employee_name` to the `legal_entity_validation_employee_result` table

Claude will guide you through the migration, including all the necessary steps, e.g.:

  • Adding the migration file, with steps like setting the timeouts and handling RLS policies
  • Adding data classification comments for all columns
  • Updating the build.gradle.kts file to exclude the new table from jOOQ

Example output:

personioPluginManager {
   // ...
    customizeJooqCodeGenerator {
        // ...
        database.withIncludeExcludeColumns(true)
        database.withExcludes(
            "public\\.(data_extraction_document)",
            "legal_entity_validation_employee_result\\.employee_name",
        )
BEGIN;

SET LOCAL statement_timeout = '30s';
SET LOCAL lock_timeout = '30s';

SET personio.company_id = 0;

ALTER TABLE legal_entity_validation_employee_result
    ADD COLUMN IF NOT EXISTS employee_email VARCHAR(255) NOT NULL DEFAULT '';

COMMENT ON COLUMN legal_entity_validation_employee_result.employee_email IS 'C-3 Confidential;PERSONAL_DATA';

COMMIT;

Why would you want this?

  • Prevent production outages: Multi-phase deployments avoid breaking running application containers during rolling updates
  • Follow company standards: Automatic data classification comments and RLS policies ensure compliance
  • Save time: No need to memorize complex migration patterns or look up documentation
  • Avoid common mistakes: Proper timeouts, locking strategies, and idempotent SQL prevent migration failures
  • Ensure consistency: All migrations follow the same battle-tested patterns used across Personio