
ClickHouse Migrations
FreeStreamline your ClickHouse migration processes with best practices.
Free · Opens the source repo
What ClickHouse Migrations does
The ClickHouse Migrations skill provides a comprehensive guide to structuring and executing migrations in ClickHouse, a powerful columnar database management system. This skill is essential for developers and data engineers who are involved in creating or modifying ClickHouse migrations, ensuring that they adhere to best practices and avoid common pitfalls. By following the detailed instructions and patterns outlined in this skill, users can effectively manage their database schema changes while maintaining data integrity and performance.
Central to the skill is a clear migration structure that emphasizes the use of specific SQL functions and node roles, tailored to different table types. Users will find quick references for various MergeTree engines and distributed tables, enabling them to select the appropriate configurations for their needs. The skill also highlights critical rules that must be followed during migrations, such as avoiding the use of the ON CLUSTER clause and ensuring that migrations are migration-only, which helps to prevent issues that can arise from mixing different types of changes.
Additionally, the skill addresses local setup parity, ensuring that all tables created via migration exist in both cloud and local development environments. This is crucial for maintaining consistency across different stages of development and deployment. The skill also provides testing guidelines, allowing users to easily re-run migrations when necessary. Overall, this skill is a valuable resource for anyone working with ClickHouse migrations, providing clarity and structure to a complex process.
When to use it
Use this skill when creating or modifying ClickHouse migrations to ensure adherence to established patterns and rules.
When not to use it
This skill may not be suitable for users who are not working with ClickHouse or those who require a more general-purpose migration tool.
What you can build with it
Creating a New Migration
When you need to create a new migration for a ClickHouse table, refer to the provided structure and critical rules to ensure compliance.
Modifying an Existing Table
If you're altering an existing ClickHouse table, use this skill to understand the necessary SQL functions and node roles.
Testing Migration Changes
Before deploying changes, utilize the testing guidelines to verify that your migration behaves as expected in both local and cloud environments.
How to install ClickHouse Migrations
View source1. Install with the skills CLI
npx skills add posthog/posthog/clickhouse-migrations --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by posthogClickHouse Migrations
Read posthog/clickhouse/migrations/AGENTS.md for comprehensive patterns, cluster setup, examples, and ingestion layer details.
Quick reference
Migration structure
operations = [
run_sql_with_exceptions(
SQL_FUNCTION(),
node_roles=[...],
sharded=False, # True for sharded tables
is_alter_on_replicated_table=False # True for ALTER on replicated tables
),
]
Node roles (choose based on table type)
[NodeRole.DATA]: Sharded tables (data nodes only)[NodeRole.DATA, NodeRole.COORDINATOR]: Non-sharded data tables, distributed read tables, replicated tables, views, dictionaries[NodeRole.INGESTION_SMALL]: Writable tables, Kafka tables, materialized views on ingestion layer
Table engines quick reference
MergeTree engines:
AggregatingMergeTree(table, replication_scheme=ReplicationScheme.SHARDED)for sharded tablesReplacingMergeTree(table, replication_scheme=ReplicationScheme.REPLICATED)for non-sharded- Other variants:
CollapsingMergeTree,ReplacingMergeTreeDeleted
Distributed engine:
- Sharded:
Distributed(data_table="sharded_events", sharding_key="sipHash64(person_id)") - Non-sharded:
Distributed(data_table="my_table", cluster=settings.CLICKHOUSE_SINGLE_SHARD_CLUSTER)
Critical rules
- NEVER use
ON CLUSTERclause in SQL statements - Always use
IF EXISTS/IF NOT EXISTSclauses - When dropping and recreating replicated table in same migration, use
DROP TABLE IF EXISTS ... SYNC - If a function generating SQL has on_cluster param, always set
on_cluster=False - Use
sharded=Truewhen altering sharded tables - Use
is_alter_on_replicated_table=Truewhen altering non-sharded replicated tables - Never write
CODEC(ZSTD(1))on a column — the server already compresses every column with ZSTD, so it buys nothing. Declare a CODEC only where it beats that default, and check theORDER BYfirst:Delta/DoubleDeltaneed the column near-sorted in storage order (a leading sort-key prefix), and lose on a column the key only buckets or omits.T64/Gorillaare ordering-independent. Put it on the storage table only — a CODEC on a Distributed or Kafka table is inert metadata that drifts from the sharded table it fronts. - Never write a
DROP COLUMNmigration yourself —DROP COLUMNcan get stuck in ClickHouse and block releases. Column removal is a two-step process: (1) the ClickHouse team drops the column directly on the cluster, then (2) you write a migration with the matchingDROP COLUMNso the codebase schema stays in sync. Never initiate the drop from a migration without the ClickHouse team having done step 1 first. - Never drop or recreate
kafka_events_json_wsorevents_json_ws_mv— these tables are a no-go zone. The MV definition differs significantly between US prod, EU prod, and dev (dozens of environment-specificmat_*columns) and those differences are not reflected in the repo. Dropping and recreating from repo SQL would destroy the environment-specific schema and break event ingestion. Any change must go through the ClickHouse team.
PR scope
A PR that contains a ClickHouse migration must be migration-only. Do not mix migration files with feature code, API changes, model changes, or frontend changes in the same PR. Migration-related files are:
- The migration file itself (
posthog/clickhouse/migrations/0NNN_*.py) - SQL definition files the migration depends on (e.g.
posthog/clickhouse/sql/*.py, table engine helpers) - Tests that directly exercise the migration or the SQL definitions it touches
If you need both a schema change and application code that uses the new schema, ship the migration first in its own PR and merge it before the application-code PR.
Local setup parity
No table should exist only in the cloud. Every table created via migration must also exist in a local dev environment.
Some migrations are cloud-guarded and skipped in local/hobby dev:
operations = (
[]
if settings.CLOUD_DEPLOYMENT not in ("US", "EU", "DEV")
else [...]
)
If you create a new table inside such a guard, you must also add its SQL function to posthog/clickhouse/schema.py in the appropriate tuple so the table gets created locally:
| Table type | Tuple in schema.py |
|---|---|
| MergeTree / base table | CREATE_MERGETREE_TABLE_QUERIES |
| Distributed / writable | CREATE_DISTRIBUTED_TABLE_QUERIES |
| Kafka consumer | CREATE_KAFKA_TABLE_QUERIES |
| Materialized view | CREATE_MV_TABLE_QUERIES |
| Non-materialized view | CREATE_VIEW_QUERIES |
| Dictionary | CREATE_DICTIONARY_QUERIES |
The only exception is tables whose definition intentionally differs per environment and is not tracked in the repo (e.g. the no-go zone events_json_ws_mv table).
Dictionary credentials: when a dictionary uses a SOURCE(CLICKHOUSE(...)), resolve the source user/password via get_clickhouse_creds(ClickHouseUser.DICT_READER) and interpolate them into the USER/PASSWORD clause — do not hardcode default/CLICKHOUSE_USER or omit credentials. This keeps dictionary auth on the dedicated low-privilege dict_reader user, decoupled from default; it falls back to default creds when the env vars are unset. See posthog/models/exchange_rate/sql.py for the pattern.
Testing
Delete entry from infi_clickhouse_orm_migrations table to re-run a migration.
Frequently asked questions about ClickHouse Migrations
Similar skills
ClickHouse Logs Queries
Efficiently manage Supabase logs with ClickHouse SQL.
EF Core D2 Database Diagram Generator
Visualize your EF Core models as D2 diagrams effortlessly.
Safe SQL Execution
Ensure secure SQL execution in Supabase applications.
Oracle to PostgreSQL Migration
Identify migration risks between Oracle and PostgreSQL.
SSMA Console
Streamline Oracle to SQL Server migrations with ease.
SQL Performance Optimization
Enhance SQL query efficiency across all databases.
