Install & Compatibility
Where this runs
tested against v0.10.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.915 runs
installs and imports cleanly · install 0.0s · import 1.140s · 24.3MB
glibcpy 3.10–3.915 runs
installs and imports cleanly · install 2.0s · import 1.140s · 26MB
23MB installed
● package 23MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
ClickhouseCluster
✓ from clickhouse_migrations.clickhouse_cluster import ClickhouseCluster
This example demonstrates how to programmatically connect to a ClickHouse instance and apply migrations from a specified directory. It creates a dummy migration file for illustration. Ensure `CH_DB_HOST`, `CH_DB_USER`, `CH_DB_PASSWORD`, `CH_DB_NAME`, and `CH_MIGRATIONS_HOME` environment variables are set or default values are appropriate for your ClickHouse instance.
import os
from clickhouse_migrations.clickhouse_cluster import ClickhouseCluster
db_host = os.environ.get('CH_DB_HOST', 'localhost')
db_user = os.environ.get('CH_DB_USER', 'default')
db_password = os.environ.get('CH_DB_PASSWORD', '')
db_name = os.environ.get('CH_DB_NAME', 'test_db')
migrations_home = os.environ.get('CH_MIGRATIONS_HOME', './migrations')
# Ensure migrations directory exists for the example
os.makedirs(migrations_home, exist_ok=True)
# Create a dummy migration file for the example
with open(f"{migrations_home}/1_create_test_table.sql", "w") as f:
f.write("CREATE TABLE IF NOT EXISTS my_table (id UInt64, name String) ENGINE = MergeTree() ORDER BY id;")
cluster = ClickhouseCluster(
db_host=db_host,
db_user=db_user,
db_password=db_password
)
try:
print(f"Applying migrations to {db_host}/{db_name} from {migrations_home}...")
cluster.migrate(
db_name=db_name,
migrations_home=migrations_home,
create_db_if_no_exists=True,
multi_statement=True
)
print("Migrations applied successfully.")
except Exception as e:
print(f"An error occurred during migration: {e}")
clickhouse-migrations --version
Debug
Known issues
breakingPython 3.7 support was dropped in version 0.5.0. Ensure your environment uses Python 3.9 or higher.fixUpgrade Python to version 3.9 or newer (e.g., Python 3.9, 3.10, 3.11, 3.12, 3.13).
affects: 0.5.0 and greater
gotchaClickHouse does not support transactions for DDL operations. If a migration fails mid-way, the schema may be left in a partially migrated and inconsistent state, which will not be automatically rolled back.fixDesign migrations to be idempotent where possible (e.g., using `IF NOT EXISTS` for `CREATE TABLE` or `ADD COLUMN`). Manually inspect the database state after a failed migration and either manually apply missing parts or revert changes if necessary.
affects: All versions
gotchaWhen using multi-statement migration files, the library splits SQL statements by semicolons. This can lead to issues if semicolons are present within string literals or comments in your SQL queries.fixAvoid semicolons within string literals or comments in multi-statement migration files. If programmatic usage, ensure `multi_statement=True` is passed.
affects: All versions
gotchaFor ClickHouse cluster deployments, `ALTER TABLE ... ADD COLUMN` statements might fail on subsequent nodes if they don't include `IF NOT EXISTS`, leading to 'DUPLICATE_COLUMN' errors.fixAlways include `IF NOT EXISTS` in `ALTER TABLE ... ADD COLUMN` statements when running migrations on a ClickHouse cluster (e.g., `ALTER TABLE my_table ON CLUSTER default ADD COLUMN IF NOT EXISTS new_col String;`).
affects: All versions
gotchaClickHouse passwords containing special characters (like `@`, `&`, `#`, `!`, `%`, `?`, `$`, `:`) may cause authentication failures when passed via CLI or environment variables if not properly URL-encoded.fixEnsure that special characters in ClickHouse passwords are URL-encoded when used in connection strings, CLI arguments, or environment variables. Consider using simpler passwords for development or secret management systems for production.
affects: All versions
Errors
Common errors & fixes
Dirty database version X. Fix and force version. Applying clickhouse migrations failed. This is mostly caused by the database being unavailable. Exiting..
A previous migration failed and left the internal `_migrations` table in a 'dirty' state, preventing further migrations.
fixFirst, investigate the failed migration (version X) to determine its actual state. If it was partially applied, manually complete or revert changes. Then, update the `_migrations` table to mark version X as clean (e.g., `INSERT INTO _migrations (version, dirty) VALUES (X, 0);`) or delete its entry if not applied. Backup your data before manual modifications.
Error: code: 62, message: Syntax error (Multi-statements are not allowed): failed at position X (end of query) (line Y, col Z): ; select 2;
ClickHouse client (or the library's internal client) received multiple SQL statements in a single query without the multi-statement mode enabled, or semicolons are misinterpreted.
fixEnsure that if you are using multi-statement SQL files, you pass `multi_statement=True` when calling `cluster.migrate()`. If using the CLI, the tool attempts to split statements by semicolon, so avoid semicolons within string literals or comments in your SQL.
error: failed to open database: code: 516, message: <db_name>: Authentication failed: password is incorrect, or there is no user with such name.
The provided ClickHouse password contains special characters that are not correctly parsed or URL-encoded by the underlying connection mechanism.
fixIf the password contains special characters, ensure they are URL-encoded when provided via environment variables (`CH_DB_PASSWORD`) or directly in connection strings. For example, `P@ssword!` should be `P%40ssword%21`.
DB::Exception: There is already a column with name 'new_column' in table 'my_table'
An `ALTER TABLE ... ADD COLUMN` statement was executed on a ClickHouse cluster where the column already existed on some nodes, leading to a duplicate column error.
fixModify your migration SQL to include `IF NOT EXISTS` when adding columns, especially in clustered environments: `ALTER TABLE my_table ON CLUSTER default ADD COLUMN IF NOT EXISTS new_column String;`.
Upgrade
Version history
0.10.0latest on PyPI · released Apr 19, 2026
Audit
Dependencies
No dependency data recorded yet.