Maintain your ClickHouse migrations.
Hermes is a simple database migration tool specifically designed for ClickHouse databases.
- Python 3.12 or higher
- ClickHouse server
- Docker (for running tests)
git clone https://github.com/your-org/hermes.git
cd hermes
uv sync- Create a configuration file (
hermes.toml):
migrations-location = "migrations"
log-level = "info"
log-to-file = true
log-to-stream = true
log-file-path = "hermes.log"- Set up environment variables (
.env):
# Option 1: Direct URI
CLICKHOUSE_URI=clickhouse://user:password@localhost:9002/default
# Option 2: Individual parameters
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=9002
CLICKHOUSE_DATABASE=default
CLICKHOUSE_USER=test
CLICKHOUSE_PASSWORD=test- Create your first migration:
uv run hermes new --message "create users table"- Run migrations:
uv run hermes upgrade headCreate a new migration file with upgrade and downgrade SQL scripts.
uv run hermes new --message "your migration description"
uv run hermes new -m "create users table"
# With custom config
uv run hermes new -m "add indexes" --config-path custom.tomlOptions:
--message, -m(required): Description of the migration--config-path: Path to configuration file (default:hermes.toml)
Run migrations forward to upgrade your database schema.
# Upgrade to latest (head)
uv run hermes upgrade head
# Upgrade to specific version
uv run hermes upgrade abc123def456
# With custom config
uv run hermes upgrade head --config-path custom.tomlOptions:
revision(required): Target revision (headfor latest, or specific version ID)--config-path: Path to configuration file (default:hermes.toml)
Run migrations backward to downgrade your database schema.
# Downgrade to base (remove all migrations)
uv run hermes downgrade base
# Downgrade to specific version
uv run hermes downgrade abc123def456
# With custom config
uv run hermes downgrade base --config-path custom.tomlOptions:
revision(required): Target revision (basefor empty database, or specific version ID)--config-path: Path to configuration file (default:hermes.toml)
Hermes uses TOML configuration files. Create a hermes.toml file in your project root:
# Migration settings
migrations-location = "migrations" # Directory to store migration files
# Logging configuration
log-level = "info" # debug, info, warning, error, critical
log-to-file = true # Write logs to file
log-to-stream = true # Write logs to console
log-file-path = "hermes.log" # Log file pathSet up your ClickHouse connection using environment variables:
Option 1: Direct URI
CLICKHOUSE_URI=clickhouse://user:password@host:port/databaseOption 2: Individual Parameters
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=9002
CLICKHOUSE_DATABASE=default
CLICKHOUSE_USER=test
CLICKHOUSE_PASSWORD=testWhen you create a new migration, Hermes generates a directory structure:
migrations/
abc123def456_create_users_table/
info.toml # Migration metadata
upgrade.sql # Forward migration SQL
downgrade.sql # Rollback migration SQL
Example upgrade.sql:
CREATE TABLE users (
id UInt64,
name String,
email String,
created_at DateTime DEFAULT now()
) ENGINE = MergeTree()
ORDER BY id;Example downgrade.sql:
DROP TABLE IF EXISTS users;# Clone repository
git clone https://github.com/your-org/hermes.git
cd hermes
# Install dependencies
uv sync --group dev
# Install pre-commit hooks
uv run pre-commit install# Run all tests
uv run pytest
# Run only unit tests (fast)
uv run pytest -m "not integration"
# Run only integration tests (requires Docker)
uv run pytest -m integration
# Run specific test file
uv run pytest src/tests/test_utils_unit.py -vTo run tests with Podman instead of Docker:
# Enable Podman socket
systemctl --user enable --now podman.socket
# Set environment variables and run tests
export DOCKER_HOST="unix:///run/user/$UID/podman/podman.sock"
export TESTCONTAINERS_RYUK_DISABLED="true"
# Now run tests normally
uv run pytest -m integration# Format code
uv run ruff format
# Lint code
uv run ruff checkFor development and testing, use the included Docker Compose setup:
# Start ClickHouse
docker compose up -d
# Stop ClickHouse
docker compose down