Skip to content

Repository files navigation

AshClickhouse

Note: This library is under active development, unstable and the API may change.

An Ash Framework data layer for ClickHouse. It implements the Ash.DataLayer behaviour using the clickhouse client.

Features

ClickHouse is a full SQL columnar store, so most Ash query features map directly:

  • CRUD (create, read, update, destroy)
  • filter, sort, limit, offset, select, distinct
  • bulk_create (batch INSERT)
  • update_query / destroy_query (via ALTER TABLE ... UPDATE/DELETE)
  • Native aggregates (count, sum, avg, min, max)
  • multitenancy (attribute- or context-based)
  • calculate, composite_primary_key, nested_expressions, boolean_filter

Not supported

  • transact / lock — ClickHouse has no multi-statement transactions
  • keyset — ClickHouse has no token-based keyset pagination (use offset)
  • upsert — ClickHouse has no ON CONFLICT (use create + update_query)
  • join — JOINs are not yet implemented
  • combine (UNION/INTERSECT) — not yet implemented
  • filter_relationship / exists (unrelated) / aggregate_relationship — not yet implemented

Installation

def deps do
  [
    {:ash_clickhouse, "~> 0.5.0"}
  ]
end

Quick start

1. Configure a Repo

defmodule MyApp.Repo do
  use AshClickhouse.Repo, otp_app: :my_app
end
# config/config.exs
config :my_app, MyApp.Repo,
  url: "http://localhost:8123",
  database: "my_app_dev"

2. Add to your supervision tree

children = [MyApp.Repo, ...]

3. Define a resource

defmodule MyApp.User do
  use Ash.Resource,
    data_layer: AshClickhouse.DataLayer,
    domain: MyApp.Domain

  import AshClickhouse.DataLayer.Dsl.Macros

  clickhouse do
    table "users"
    repo MyApp.Repo
    engine "MergeTree()"
    order_by "id"
  end

  attributes do
    uuid_primary_key :id
    attribute :name, :string
    attribute :email, :string
  end

  actions do
    defaults [:create, :read, :update, :destroy]
  end
end

4. Create the database and tables

mix ash_clickhouse.setup
mix ash_clickhouse.migrate

For production releases (no Mix available), use AshClickhouse.Release.

5. Use it

{:ok, user} = Ash.create(MyApp.User, %{name: "John", email: "john@example.com"})
users = Ash.read!(MyApp.User)

See Getting Started for the full walkthrough.

Configuration

Resource (clickhouse DSL)

Option Description
table Table name (overrides default)
repo The AshClickhouse.Repo module
database Database to use (overrides repo default)
engine ClickHouse table engine (default "MergeTree()")
order_by ORDER BY expression for the engine
partition_by PARTITION BY expression
primary_key Explicit primary key columns
settings Engine settings string
base_filter Filter applied to all queries
default_context Context merged into every query/changeset
migrate Whether to include in migrations (default true)
index Declares a data-skipping index (repeatable)

Data-skipping indexes

ClickHouse has no B-tree indexes; it uses data-skipping indexes (minmax, set, bloom_filter, ngrambf_v1, tokenbf_v1) declared in the table DDL. Declare them inside the clickhouse block — the index macro may be repeated, and granularity defaults to 1:

clickhouse do
  table "events"
  repo MyApp.Repo
  order_by "id"

  index name: :idx_user_id, expression: "user_id", type: "bloom_filter"
  index name: :idx_created_at, expression: "created_at", type: "minmax", granularity: 4
end

Indexes are additive only. mix ash_clickhouse.migrate emits them in the CREATE TABLE statement for new tables, and issues ALTER TABLE ... ADD INDEX IF NOT EXISTS for existing tables that lack them. Changing an existing index's type/expression is not auto-applied — ADD INDEX IF NOT EXISTS no-ops on a name collision. The migrate task instead prints a warning (with the exact DROP INDEX + ADD INDEX SQL to run) when an existing index's stored definition differs from the DSL. To change a definition, manually ALTER TABLE ... DROP INDEX and re-run the migration. (A typo in type is rejected at compile time.)

Repo

Option Default Description
url "http://localhost:8123" ClickHouse HTTP URL
username "default" Credentials username
password "" Credentials password
database nil Default database name
pool_size 10 Connection pool size
pool_timeout 30_000 Pool checkout timeout (ms)
ping_retry 30_000 Ping retry interval (ms)

Documentation

Guides are available under guides/:

License

Apache-2.0. See LICENSE.

About

ClickHouse data layer for Ash

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages