Skip to content

About

Database migrations with SQL scripts and C# code: downgrades, long-running migrations, policies

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

 
 

Repository files navigation

Curiosus.Migrations

Database migration framework for .NET: raw SQL and C# code migrations, downgrades, long-running data migrations and per-environment policies for PostgreSQL and SQL Server.

Build License NuGet Downloads Coverage Docs

Renamed: formerly Curiosity.Migrations* by SIIS Ltd. Since 5.0.0 the packages are published as Curiosus.Migrations* by curiosus-dev. To migrate, replace Curiosity with Curiosus in package references and code. -- CURIOSITY: directives in SQL scripts keep working.

Why use it

Curiosus.Migrations is a database migration framework for .NET (net9.0 and net10.0; stay on 5.x for older runtimes) that gives you precise control over how your database evolves. It keeps raw SQL scripts and C# code migrations in one ordered history, so a schema change and the data migration that goes with it are versioned, applied and rolled back together.

Unlike ORM-specific migration tools, Curiosus.Migrations is database-focused and designed for scenarios where you need fine-grained control over migration execution, especially for large production databases where heavy data migrations must not block a deployment.

🔧 Precise Control

Write raw SQL when you need optimal performance, or use C# code when you need complex logic. You control exactly what runs against your database.

🚀 Production-Ready

Long-running migration support and policies that decide what runs in each environment: quick schema changes on deployment, heavy data migrations separately.

🔄 Bidirectional

Downgrade scripts and code migrations roll the database back to a target version when a deployment doesn't go as planned.

📊 Progressive Migrations

Separate long-running data migrations from quick schema changes to keep your application responsive during upgrades.

🧪 Testability

Create and initialize test databases with specific migration states for reliable integration testing.

🧩 Extensibility

Customize where migrations come from, how they're logged, and how they're applied to fit your workflow.

Features

Migration Types

Safety and Control

Extensibility

Quick start

Installation

# Install core package
dotnet add package Curiosus.Migrations

# Install database provider (PostgreSQL or SQL Server)
dotnet add package Curiosus.Migrations.PostgreSQL
# or
dotnet add package Curiosus.Migrations.SqlServer

Basic Setup

Put SQL scripts named by version into a directory: 1.0-create_users.sql, 1.1.up.sql with its 1.1.down.sql, and so on. Then configure and run the engine:

using System.Reflection;
using Curiosus.Migrations;
using Curiosus.Migrations.PostgreSQL;

var builder = new MigrationEngineBuilder();

// UseScriptMigrations() and UseCodeMigrations() return the providers, not the builder: configure them separately
builder.UseScriptMigrations().FromDirectory("./Migrations");
builder.UseCodeMigrations().FromAssembly(Assembly.GetExecutingAssembly());
builder.ConfigureForPostgreSql("Host=localhost;Database=myapp;Username=postgres;Password=secret");
builder.UseUpgradeMigrationPolicy(MigrationPolicy.AllAllowed);

var migrationEngine = builder.Build();
var result = await migrationEngine.UpgradeDatabaseAsync();

if (!result.IsSuccessfully)
{
    throw new InvalidOperationException(
        $"Migration {result.FailedMigration?.Version} failed: {result.ErrorCode} {result.ErrorMessage}",
        result.Exception);
}

Console.WriteLine($"Applied {result.AppliedMigrations.Count} migrations");

The engine creates the database and the migration history table when they are missing. A complete runnable example with script, code and downgrade migrations is in samples/Curiosus.Migrations.Sample.

Get started quickly with the Quick Start Guide or dive into Core Concepts.

Running in production

No concurrency lock yet. The engine doesn't lock the database while it migrates, so two instances starting at the same time can apply the same migration twice or fail on the journal. Until #32 lands, run migrations from one place: a Kubernetes Job or init container, a deployment pipeline step, or the startup of a single replica.

Supported Databases


PostgreSQL

SQL Server

MySQL/MariaDB (#37) and SQLite (#38) are planned for v7, after the engine rework that makes a new database a small dialect (#36). A custom IMigrationConnection can add any other database.

Comparing with Alternatives

As of October 2026. ✅ supported, ⚠️ partly or with caveats, ❌ not supported, 💰 paid editions only.

Curiosus.Migrations EF Core Migrations FluentMigrator DbUp grate Flyway Liquibase
Migrations written as SQL + C# code C# generated from the EF model (+ raw SQL) Fluent C# API (+ raw SQL) SQL (+ IScript code) SQL SQL (+ Java) XML/YAML/JSON/SQL changelogs
Databases PostgreSQL, SQL Server Any EF Core relational provider 6 7 5 20+ 50+
Downgrade / rollback ✅ Hand-written, free ✅ Generated Down() ✅ Down(), auto-reversing ❌ ❌ 💰 Undo ✅ (targeted rollback 💰)
Long-running vs short-running policies ✅ ❌ ⚠️ Tags, profiles ⚠️ Script filters ⚠️ Environment scripts ⚠️ Cherry-pick 💰 ⚠️ Contexts, labels
Dependencies between migrations ✅ ❌ ❌ ❌ ❌ ❌ ⚠️ Changelog order
C# migrations with DI ✅ ⚠️ No DI in migrations ✅ ⚠️ IScript ❌ ❌ ❌
Concurrency lock ❌ #32 ✅ Since EF Core 9 ❌ ❌ Not documented ✅ ✅
Checksums, drift detection ❌ #33 ⚠️ Pending model changes check ❌ ❌ ✅ ✅ (drift report 💰) ✅ (drift 💰)
Repeatable migrations ❌ #39 ❌ ⚠️ Maintenance stages ✅ ✅ ✅ ✅
CLI, dry-run, SQL preview ❌ #40, #42 ✅ dotnet ef, bundles, scripts ✅ dotnet-fm ⚠️ Library ✅ ✅ ✅
License MIT MIT Apache-2.0 MIT MIT Apache-2.0 core, paid editions FSL core, paid editions

The gaps are planned for v7, see the roadmap. Evolve had checksums and locking but has had no stable release since 3.2.0 (June 2023); RoundhousE is superseded by grate.

Choose Curiosus.Migrations when you mix hand-tuned SQL with C# data migrations on PostgreSQL or SQL Server, need heavy backfills kept out of the deployment path, and want free downgrades. Choose something else when your app is EF Core-centric with one schema owner (EF Core Migrations), you target many database engines or want a fluent schema DSL (FluentMigrator), you only need forward-only SQL scripts (DbUp, or grate with hash checks and a CLI), or a DBA-led team needs compliance and drift reports (Flyway, Liquibase).

For a detailed comparison, see The Philosophy Behind Curiosus.Migrations.

Available packages

Package Version Downloads Coverage
Curiosus.Migrations NuGet NuGet Coverage
Curiosus.Migrations.PostgreSQL NuGet NuGet Coverage
Curiosus.Migrations.SqlServer NuGet NuGet Coverage
Curiosus.Migrations.Utils NuGet NuGet Coverage

Support

License

Curiosus.Migrations is licensed under the MIT License.

About

Database migrations with SQL scripts and C# code: downgrades, long-running migrations, policies

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages