PostgreSQL Provider

The Hyperbee.Migrations.Providers.Postgres package provides PostgreSQL support for Hyperbee Migrations. It handles schema changes, table management, and data seeding through code and resource-based migrations. For cross-cutting concepts like profiles, cron, and journaling, see Concepts.

Installation

dotnet add package Hyperbee.Migrations.Providers.Postgres

Configuration

Register the Npgsql data source and migration services with the DI container:

services.AddNpgsqlDataSource( connectionString );

services.AddPostgresMigrations( options =>
{
    options.SchemaName = "migration";               // default
    options.TableName = "ledger";                   // default
});

Locking

The provider uses a PostgreSQL-based distributed lock to prevent simultaneous migration runners.

services.AddPostgresMigrations( options =>
{
    options.LockingEnabled = true;                                  // default
    options.LockName = "ledger_lock";                               // lock identifier
    options.LockMaxLifetime = TimeSpan.FromHours( 1 );             // max time-to-live
});

Code Migration Example

Inject NpgsqlDataSource to interact with PostgreSQL directly:

[Migration( 3000 )]
public class SeedData( NpgsqlDataSource dataSource, ILogger<SeedData> logger ) : Migration
{
    public override async Task UpAsync( CancellationToken cancellationToken = default )
    {
        logger.LogInformation( "Seeding data via code migration" );

        await using var conn = await dataSource.OpenConnectionAsync( cancellationToken );
        await using var cmd = conn.CreateCommand();

        cmd.CommandText = "INSERT INTO sample.users (name, email) VALUES ('Bob Johnson', 'bob@example.com')";
        await cmd.ExecuteNonQueryAsync( cancellationToken );
    }
}

Resource Migration Example

Use PostgresResourceRunner<T> to execute embedded SQL files. Unlike other providers, Postgres uses plain .sql files – not JSON statement wrappers.

[Migration( 1000 )]
public class CreateInitialSchema( PostgresResourceRunner<CreateInitialSchema> resourceRunner ) : Migration
{
    public override async Task UpAsync( CancellationToken cancellationToken = default )
    {
        // run all .sql files matching this migration
        await resourceRunner.AllSqlFromAsync( cancellationToken );
    }
}

[Migration( 2000 )]
public class AddSecondaryIndexes( PostgresResourceRunner<AddSecondaryIndexes> resourceRunner ) : Migration
{
    public override async Task UpAsync( CancellationToken cancellationToken = default )
    {
        // run specific .sql files
        await resourceRunner.SqlFromAsync( [
            "create_indexes.sql"
        ], cancellationToken );
    }
}

Statement Format

Resource files are plain .sql files containing standard PostgreSQL statements. Each file can contain one or more SQL statements separated by semicolons.

Example (create_schema.sql):

CREATE SCHEMA IF NOT EXISTS sample;

CREATE TABLE IF NOT EXISTS sample.users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL,
    active BOOLEAN DEFAULT true,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Document Format

The Postgres provider does not use JSON document files. All data operations are performed through .sql files using standard SQL INSERT, UPDATE, or COPY statements.

Resources/1000-CreateInitialSchema/
  create_schema.sql
  create_tables.sql
  seed_data.sql

Provider Options Reference

Option Type Default
SchemaName string “migration”
TableName string “ledger”
LockName string “ledger_lock”
LockMaxLifetime TimeSpan 1 hour
LockingEnabled bool true

© Stillpoint Software.

Hyperbee Migration Docs