Clicksuite: ClickHouse Migration Tool
Clicksuite is a robust CLI and programmatic tool designed for managing ClickHouse database migrations. It supports environment-specific configurations, allowing for separate SQL definitions across development, test, and production environments. Key features include multi-statement migration support, environment variable interpolation for secure credential management (e.g., `${ENV_VAR}`), automatic `schema.sql` generation for multi-database schema tracking, and a dry-run mode for previewing migrations. The tool also provides verbose logging control and comprehensive migration management commands (apply, rollback, reset, status). It is currently at version 1.7.4, with a steady release cadence addressing fixes and adding features like programmatic usage settings and multi-statement support. It ships with full TypeScript types, making it suitable for modern JavaScript and TypeScript projects.
Common errors
-
Error: ConnectException: Connection refused
cause Clicksuite could not establish a connection to the ClickHouse instance at the specified `CLICKHOUSE_URL`.fixCheck if your ClickHouse instance is running and accessible from where Clicksuite is executed. Verify the `CLICKHOUSE_URL` environment variable for correct host, port, and credentials. Ensure no firewalls are blocking the connection. -
Error: ENOENT: no such file or directory, stat './migrations'
cause The migrations directory specified (or defaulted to `./migrations`) does not exist when Clicksuite attempts to read or write migration files.fixRun `clicksuite init` to create the default migrations directory and the `__clicksuite_migrations` table. If using a custom directory, ensure `CLICKSUITE_MIGRATIONS_DIR` is correctly set and the directory exists. -
Error: Table '__clicksuite_migrations' does not exist.
cause Clicksuite's internal migration tracking table `__clicksuite_migrations` is missing in the specified database.fixRun `clicksuite init` to initialize the project and create the necessary tracking table. If using a custom database for migrations, ensure `CLICKSUITE_MIGRATIONS_DATABASE` is correctly configured.
Warnings
- deprecated The `database` setting in programmatic usage has been deprecated. It should be replaced with the new `migrationsDatabase` option.
- gotcha When installing Clicksuite globally (`npm install -g clicksuite`), ensure your Node.js version meets the `engines` requirement (>=16.0.0). Older Node.js versions may lead to unexpected behavior or installation failures.
- gotcha Environment variables are crucial for Clicksuite's operation. If `CLICKHOUSE_URL` is not properly configured in your `.env` file or environment, Clicksuite will fail to connect to your ClickHouse instance.
Install
-
npm install clicksuite -
yarn add clicksuite -
pnpm add clicksuite
Imports
- ClickHouseMigrator
import { ClickHouseMigrator } from 'clicksuite'; - runCli
import { runCli } from 'clicksuite/dist/cli'; - MigrationConfig
import type { MigrationConfig } from 'clicksuite';
Quickstart
import { ClickHouseMigrator } from 'clicksuite';
import path from 'path';
// Load environment variables (e.g., using 'dotenv')
import 'dotenv/config';
async function runMigrations() {
const config = {
clickhouseUrl: process.env.CLICKHOUSE_URL ?? 'http://default@localhost:8123/my_database',
migrationsDir: path.resolve(process.cwd(), 'migrations'),
migrationsDatabase: process.env.CLICKSUITE_MIGRATIONS_DATABASE ?? 'default',
environment: process.env.CLICKSUITE_ENVIRONMENT ?? 'development',
verbose: true,
skipSchemaUpdate: false,
};
const migrator = new ClickHouseMigrator(config);
console.log('Applying migrations...');
await migrator.up();
console.log('Migrations applied successfully.');
// Example of generating a new migration (typically done via CLI)
// await migrator.generate('create_users_and_products_tables');
// Example of rolling back the last migration
// console.log('Rolling back last migration...');
// await migrator.down();
// console.log('Last migration rolled back.');
}
runMigrations().catch(error => {
console.error('Migration failed:', error);
process.exit(1);
});