Raw SQL migrations and contexts for ClickHouse
$ dotnet add package ClickHouse.FacadesZero-ORM .NET package for managing ClickHouse migrations and organizing raw SQL through structured database contexts.
Makes it easy to separate concerns across features, services, or tables.
Built on ClickHouse.Driver (ClickHouse.Client for version < 3.0.0) and tested in production.
[!NOTE] This is an unofficial package and is not affiliated with or endorsed by ClickHouse Inc.
"ClickHouse" is a registered trademark of ClickHouse Inc. — clickhouse.com
Implement IClickHouseMigrationInstructions and IClickHouseMigrationsLocator
(example)
and register them as DI services
services.AddClickHouseMigrations<ClickHouseMigrationInstructions, ClickHouseMigrationsLocator>();
You can request IClickHouseMigrator service or use IServiceProviderExtensions to manage migrations
await serviceProvider.ClickHouseMigrateAsync();
Add ClickHouseMigration inheritor with ClickHouseMigration attribute
[ClickHouseMigration(202310240941, "ExampleMigration")]
public class ExampleMigration : ClickHouseMigration
{
protected override void Up(ClickHouseMigrationBuilder migrationBuilder)
{
// migrationBuilder.AddRawSqlStatement("create table if not exists ...")
}
protected override void Down(ClickHouseMigrationBuilder migrationBuilder)
{
// migrationBuilder.AddRawSqlStatement("drop table if exists ...")
}
}
The index of ClickHouseMigrationAttribute is used to order migrations. It's best to always use idempotent statements (for example with if [not] exists) since migration may fail.
Implement the following class inheritors: ClickHouseContext<TContext>, ClickHouseContextFactory<TContext>, ClickHouseFacade<TContext>
(example)
and register them as DI services
services.AddClickHouseContext<ExampleContext, ExampleContextFactory>(builder => builder
.AddFacade<UsersFacade>()
.AddFacade<OrdersFacade>());
Request IClickHouseContextFactory<TContext> service to create context
await using var context = await contextFactory.CreateContextAsync();
var ordersFacade = context.GetFacade<OrdersFacade>();
await ordersFacade.GetOrders();
You can create as many contexts as you need with any number of facades. Facades are built via DI and are stateful within context lifetime.
[!NOTE] You can perform migrations on your ClickHouse database without the necessity of implementing contexts.
For a deeper understanding and practical use cases of how to implement migrations and facades, please refer to the examples folder provided in the repository.