{"id":20834130,"url":"https://github.com/zifter/clickhouse-migrations","last_synced_at":"2026-04-19T18:01:14.939Z","repository":{"id":45174364,"uuid":"442099765","full_name":"zifter/clickhouse-migrations","owner":"zifter","description":"Simple migration tool for clickhouse database","archived":false,"fork":false,"pushed_at":"2025-07-20T15:16:19.000Z","size":114,"stargazers_count":23,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-20T17:24:47.606Z","etag":null,"topics":["clickhouse","database","migration","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zifter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-12-27T08:34:43.000Z","updated_at":"2025-07-20T15:16:23.000Z","dependencies_parsed_at":"2024-12-27T06:08:10.944Z","dependency_job_id":"a35e8da0-8dfb-4e0f-b3d8-2b46c2854592","html_url":"https://github.com/zifter/clickhouse-migrations","commit_stats":{"total_commits":40,"total_committers":4,"mean_commits":10.0,"dds":0.625,"last_synced_commit":"d8d909cdf0a08412cf1b109b75362f7d072c4e82"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/zifter/clickhouse-migrations","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zifter%2Fclickhouse-migrations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zifter%2Fclickhouse-migrations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zifter%2Fclickhouse-migrations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zifter%2Fclickhouse-migrations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zifter","download_url":"https://codeload.github.com/zifter/clickhouse-migrations/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zifter%2Fclickhouse-migrations/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267606013,"owners_count":24114636,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clickhouse","database","migration","python"],"created_at":"2024-11-18T00:18:16.161Z","updated_at":"2026-04-19T18:01:14.926Z","avatar_url":"https://github.com/zifter.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![ci](https://github.com/zifter/clickhouse-migrations/actions/workflows/ci.yaml/badge.svg)](https://github.com/zifter/clickhouse-migrations/actions/workflows/ci.yaml)\n[![release](https://img.shields.io/github/release/zifter/clickhouse-migrations.svg)](https://github.com/zifter/clickhouse-migrations/releases)\n[![PyPI version](https://badge.fury.io/py/clickhouse-migrations.svg)]([https://badge.fury.io/py/clickhouse-migrate](https://pypi.org/project/clickhouse-migrations/))\n[![supported versions](https://img.shields.io/pypi/pyversions/clickhouse-migrations.svg)](https://pypi.org/project/clickhouse-migrations/)\n[![downloads](https://img.shields.io/pypi/dm/clickhouse-migrations.svg)](https://pypi.org/project/clickhouse-migrations/)\n[![my site](https://img.shields.io/badge/site-my%20blog-yellow.svg)](https://zifter.github.io/)\n\n# Clickhouse Migrations\n\nPython library for creating and applying migrations in ClickHouse database.\n\nDevelopment and Maintenance of large-scale db systems many times requires constant changes to the actual DB system.\nHolding off the scripts to migrate these will be painful.\n\n## Features:\n* Supports multi statements - more than one query per migration file.\n* Allow running migrations out-of-box\n* Simple file migrations format: {VERSION}_{name}.sql\n* Supports Cluster deployments, makes sure that migrations state is consistent on all cluster nodes\n\n## Known alternatives\nThis package originally forked from [clickhouse-migrator](https://github.com/delium/clickhouse-migrator).\n\nPackage | Differences\n-------|---------\n[clickhouse-migrator](https://github.com/delium/clickhouse-migrator) | Doesn't support multistatement in a single file , to heavy because of pandas, looks like abandoned\n[django-clickhouse](https://github.com/carrotquest/django-clickhouse) | Need django\n[clickhouse-migrate](https://github.com/trushad0w/clickhouse-migrate) | Doesn't support multistatement\n\n## Installation\n\nYou can install from pypi using `pip install clickhouse-migrations`.\n\n## Migration files\n\nMigration files follow the naming convention `{VERSION}_{name}.sql`, e.g. `001_init.sql`, `002_add_users.sql`.\n\nEach file contains one or more SQL statements separated by semicolons:\n\n```sql\n-- migrations/001_init.sql\nCREATE TABLE mydb.events (\n    id     UInt32,\n    name   String\n) ENGINE = MergeTree()\nORDER BY id;\n\nALTER TABLE mydb.events ADD COLUMN created_at DateTime DEFAULT now();\n```\n\n## Usage\n\n### In command line\n```bash\nclickhouse-migrations --db-host localhost \\\n    --db-port 9000 \\\n    --db-user default \\\n    --db-password secret \\\n    --db-name test \\\n    --migrations-dir ./migrations\n```\n\nAlternatively, connect via URL:\n```bash\nclickhouse-migrations --db-url clickhouse://default:secret@localhost:9000/test \\\n    --migrations-dir ./migrations\n```\n\nAll options can also be set via environment variables:\n\nCLI flag | Environment variable | Default\n---------|---------------------|--------\n`--db-host` | `DB_HOST` | `localhost`\n`--db-port` | `DB_PORT` | `9000`\n`--db-user` | `DB_USER` | `default`\n`--db-password` | `DB_PASSWORD` | *(empty)*\n`--db-name` | `DB_NAME` | —\n`--db-url` | `DB_URL` | —\n`--migrations-dir` | `MIGRATIONS_DIR` | `./migrations`\n`--cluster-name` | `CLUSTER_NAME` | —\n`--multi-statement` | `MULTI_STATEMENT` | `true`\n`--create-db-if-not-exists` | `CREATE_DB_IF_NOT_EXISTS` | `true`\n`--dry-run` | `DRY_RUN` | `false`\n`--fake` | `FAKE` | `false`\n`--secure` | `SECURE` | `false`\n`--log-level` | `LOG_LEVEL` | `WARNING`\n\n### In code\n```python\nfrom clickhouse_migrations.clickhouse_cluster import ClickhouseCluster\n\ncluster = ClickhouseCluster(\n    db_host=\"localhost\",\n    db_port=9000,\n    db_user=\"default\",\n    db_password=\"secret\",\n)\ncluster.migrate(\n    db_name=\"test\",\n    migration_path=\"./migrations\",\n    cluster_name=None,\n    create_db_if_no_exists=True,\n    multi_statement=True,\n    dryrun=False,\n    fake=False,\n)\n```\n\nAlternatively, connect via URL:\n```python\ncluster = ClickhouseCluster(db_url=\"clickhouse://default:secret@localhost:9000/test\")\ncluster.migrate(db_name=\"test\", migration_path=\"./migrations\")\n```\n\nParameter | Description | Default\n-------|-------------|--------\n`db_host` | ClickHouse database hostname | `localhost`\n`db_port` | ClickHouse database port | `9000`\n`db_user` | ClickHouse user | `default`\n`db_password` | ClickHouse password | *(empty)*\n`db_url` | ClickHouse connection URL (alternative to individual params) | —\n`db_name` | ClickHouse database name | —\n`migration_path` | Path to directory with migration files | `./migrations`\n`explicit_migrations` | Explicit list of migrations to apply | `[]`\n`cluster_name` | Name of ClickHouse topology cluster from `\u003cremote_servers\u003e` | —\n`create_db_if_no_exists` | Create the database if it does not exist | `True`\n`multi_statement` | Allow multiple statements per migration file | `True`\n`dryrun` | Print migrations without executing them | `False`\n`fake` | Mark migrations as applied without executing SQL | `False`\n`secure` | Use secure (TLS) connection | `False`\n\n### Notes\nThe ClickHouse driver does not natively support executing multiple statements in a single query.\nTo allow for multiple statements in a single migration, you can use the `multi_statement` param.\nThere are two important caveats:\n* This mode splits the migration text into separately-executed statements by a semi-colon `;`. Thus cannot be used when a statement in the migration contains a string with a semi-colon.\n* The queries are not executed in any sort of transaction/batch, meaning you are responsible for fixing partial migrations.\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=zifter/clickhouse-migrations\u0026type=Date)](https://star-history.com/#zifter/clickhouse-migrations\u0026Date)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzifter%2Fclickhouse-migrations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzifter%2Fclickhouse-migrations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzifter%2Fclickhouse-migrations/lists"}