@fjall/clickhouse
v2.6.0
Published
Runtime helpers for ClickHouse migration containers — user provisioning, SQL file application, connection retry. Consumes the manifest contract published by @fjall/components-infrastructure ClickHouseDatabase.
Keywords
Readme
@fjall/clickhouse
Runtime helpers for ClickHouse migration containers. Consumes the user manifest published by @fjall/components-infrastructure ClickHouseDatabase and provisions workload users in writable users_local storage. Also ships a generic SQL-file runner and a connection-retry helper.
Installation
npm install @fjall/clickhouse @clickhouse/client@clickhouse/client is a peer dependency — the consumer supplies the runtime client.
Env-var contract
The framework's commitment is the env-var shape, not this package's API. A customer rolling their own consumer reads the same env vars.
| Env var | Shape | Producer |
| -------------------------- | --------------------------------------- | --------------------------------------------------------- |
| CLICKHOUSE_MANAGED_USERS | JSON Array<string> of user names | ClickHouseDatabase.getMigrationContributions() |
| USER_<NAME>_PASSWORD | plaintext (one per managed-users entry) | ECS executionRole + Secrets Manager (no runtime SDK call) |
The manifest carries names only — the schema admin (XML-defined) is NOT included, and profile binding is the customer SQL's job (ALTER USER <name> SETTINGS PROFILE '<profile>').
The constant name + env-name helper + schema live in @fjall/util/migration:
import {
CLICKHOUSE_MANAGED_USERS_ENV,
ManagedUserNamesSchema,
userPasswordEnvName,
} from "@fjall/util/migration";This package re-exports them for convenience so consumers don't need two imports.
Usage
import {
connectWithRetry,
createConsoleMigrationLogger,
provisionUsersFromEnv,
runSqlMigrations,
} from "@fjall/clickhouse";
import { createClient } from "@clickhouse/client";
const logger = createConsoleMigrationLogger("migration-runner");
const client = createClient({ url, username, password, database });
await connectWithRetry(client, { label: "user-provision", logger });
await provisionUsersFromEnv({ client, logger });
await runSqlMigrations({ client, dir: "./clickhouse-init", logger });provisionUsersFromEnv is idempotent — it issues CREATE USER IF NOT EXISTS then ALTER USER for every manifest entry, so repeated invocations are safe.
Rolling your own consumer
The env-var contract above is stable. A customer who prefers their own provisioner reads the same env vars; this package's helpers are convenience wrappers. The framework commits to the env shape, not to this package.
If rolling your own, you'll want to replicate:
- single-quote-escape the password literal (
'→'') before string-interpolating intoIDENTIFIED WITH … BY '…' - mask passwords in any log output (use
maskSensitiveOutputfrom@fjall/util) - order
CREATE USER IF NOT EXISTSbeforeALTER USERso re-provisioning realigns drifted credentials - place provisioning BEFORE any migration-hash idempotency gate
- regex-validate user names before string-interpolating into SQL (CH doesn't bind identifier parameters)
Licence
Proprietary — see LICENSE.
