Redgate Flyway

Making Generated Migrations More Portable with Placeholder Replacement

Flyway's generate command has always been powerful for creating migration scripts that capture schema differences between environments. Now we've made those generated migrations even more useful by introducing placeholder replacement support.

Previously, when you used the generate command to create migration scripts from schema differences, the generated SQL would contain hard-coded schema names, database names, or other environment-specific values. This meant that generated migrations were often tied to a specific environment and couldn't easily be reused across different stages of your deployment pipeline.

You would see generated migrations like this:

CREATE TABLE [dbo].[customers] (
    id INT NOT NULL,
    name VARCHAR(255) NOT NULL
);

What we've done is introduce the -generate.usePlaceholders=true parameter that tells the generate command to preserve placeholder syntax in the generated migration scripts (available from Flyway v11.10.0).

Enabling the feature

When using the generate command, simply add the -generate.usePlaceholders=true parameter:

Command Line

flyway diff \
    -diff.source=environment1 \
    -diff.target=environment2 \
generate \
    -generate.usePlaceholders=true \
    -generate.types="versioned" \
    -generate.force=true

Docker

docker run --rm \
    -v "$(pwd)/conf:/flyway/conf" \
    -v "$(pwd)/migrations:/flyway/migrations" \
    redgate/flyway \
diff \
    -diff.source=default \
    -diff.target=target \
generate \
    -generate.usePlaceholders=true \
    -generate.types="versioned" \
    -generate.force=true

Configuration

Define your placeholders in your flyway.toml configuration file:

[flyway.placeholders]
schema="dbo"
database="myapp"
environment="prod"

What you'll see

Instead of generating environment-specific migrations, Flyway will now generate portable migrations using your placeholder syntax:

Before (without placeholder replacement):

CREATE TABLE [dbo].[customers] (
    id INT NOT NULL,
    name VARCHAR(255) NOT NULL
);

After (with -generate.usePlaceholders=true):

CREATE TABLE [${schema}].[customers] (
    [id] [int] NOT NULL,
    [name] [varchar] (255) NOT NULL
);

Benefits

Environment Portability: Generated migrations can be deployed across development, staging, and production environments without modification.

Schema Flexibility: Perfect for multi-tenant applications where each tenant uses a different schema name.

CI/CD Integration: Generated migrations work seamlessly in automated deployment pipelines where environment-specific values are injected at runtime.

Consistency: Maintains the same placeholder patterns you're already using in your hand-written migrations.

Use Cases

This feature is particularly valuable when:

  • Capturing customizations: Generate migrations from production customizations that need to be applied to other environments
  • Schema synchronization: Keep multiple environments in sync while maintaining environment-specific naming conventions
  • Automated drift detection: Generate corrections for schema drift that can be applied across all environments
  • Multi-tenant deployments: Create tenant-specific migrations that work regardless of the tenant's schema naming


Didn't find what you were looking for?