- Add
SkipIndexTextfor full-text index generation, introspection, pull, and drift. Preserve quoted SQL literals, normalize ClickHouse’s fixed granularity, and reject malformed or unsupported metadata. Exercise adversarial round trips and actual indexed search results on ClickHouse 26.3 and 26.8. - Native Kafka table definitions without sorting keys, escaped literal settings, pull round trips, and normalized live drift/check comparisons.
- Validation and migration guards reject unsupported Kafka changes before writing artifacts. Offline drift/check report changes requiring replacement; explicit drop/create migrations preserve the existing destructive-operation gate.
- Kafka ingestion and replacement integration tests on ClickHouse 25.3 and 26.3.
- Preserve quoted clause names, delimiters, whitespace, and escaped trailing backslashes in table introspection and migration statement splitting.
Full parity with the TypeScript chkit. Every remaining gap is closed;
the parity decision log lives in DRIFT.md.
- Dictionary primitive —
dictionary()DSL, validation (8 codes),CREATE / CREATE OR REPLACE / RENAME / DROP DICTIONARYplanning with[HIDDEN]-password handling,--rename-dictionary, create-dictionary parser, pull introspection + rendering, codegen Pydantic models, drift and safety-marker coverage. - Phase-2 backfill engine — chunking planner (partition slices, byte
budgets, all split strategies), chunk-execution SQL builder with MV
replay (every feeding MV via
UNION ALL, chunks sized from the MV source), async submit/poll execution loop with atomic checkpointing, realplan/run/resume/doctorcommands, managedbackfill submitto ObsessionDB jobs with console deep-links, and theon_checkfindings (backfill_required_pending, ...). - Index-only projections (
{"index": ..., "type": ...}) and function expressions inprimaryKey/orderBy. - CLI: top-level
chkit codegenandchkit obsessiondb <cmd>shortcuts;chkit plugin <name> <cmd>now forwards the command's own--flags. - Config: function-style configs —
define_config(lambda env: ...)withChxConfigEnv(command, mode);check.failOnExtraObjects; per-tablepluginsfield ontable().
- Wheel now packages
chkit_plugin_codegenandchkit_plugin_backfill(previously missing frompip install chkit-py). ClickHouseClient.submit()crashed on every live call (unsupportedquery_id=kwarg) — affectedmigrate --applyasync statements.- Snapshots serialize with
exclude_none, matching TSJSON.stringifykey omission so TS tooling reads Python-written snapshots correctly. - JS-fidelity fixes across ports:
Number()/String()semantics for chunk boundaries,Date.parsesub-millisecond truncation, WHATWGURL.originenvironment fingerprints (TS-written plans now run under Python), JS\swhitespace class in key-clause comparison,??vs truthiness in drift primary-key fallback. - Plugin command
--jsonoutput prints real JSON (was Python dict repr). - Table-clause parsing no longer swallows clauses when a projection's
SELECT contains
ORDER BY, and a primary key derived fromORDER BYno longer reads as drift.
Documentation refresh — no code changes.
PARITY.md— TypeScript ↔ Python parity matrix listing every TS module / command / flag, what's 1:1 today, what's intentionally deferred, and the rationale behind each deferral. Lives at the repo root so contributors can pick a deferred item and port it without spelunking through the TS source.
README.mdrewritten:- Drops the "port-in-progress" note (the first base is done).
- Adds an explicit TypeScript-parity section summarising what's covered.
- Adds a Quickstart that walks through
init→generate→migrate --apply→status/check/drift. - Points contributors at
PARITY.mdfor the full divergence matrix.
Major TS parity release. The CLI now matches the TypeScript reference 1:1
across generate, migrate, status, check, and drift.
- Migration SQL artifact format matches
packages/codegen/src/index.ts:- Header comments:
chkit-migration-format: v1,generated-at,cli-version,definition-count,operation-count,rename-suggestion-count,risk-summary. - Per-operation comments:
-- operation: <type> key=<key> risk=<risk>. - Rename hint comments:
-- rename-suggestion: .... - Filename:
<timestamp>_<safe_name>.sqlwith_001,_002, ... suffix on collision (matches TSsafeName+collisionIndexbehaviour).
- Header comments:
chkit generate --name <name>replaces the old--label. Adds--migration-id <id>(override timestamp prefix) and--dryrun(print plan without writing artifacts), matching the TS flag set verbatim.chkit migratedefaults to plan/preview like TS. Use--apply(or alias--execute) to actually run statements. Added--allow-destructivefor migrations whose plan containsrisk=dangeroperations (exit code 3 when blocked, mirroring TS).- ClickHouse-backed journal: applied migrations are recorded in a
_chkit_migrationstable in the target database, schema identical topackages/cli/src/runtime/journal-store.ts(ReplacingMergeTree(applied_at) ORDER BY (name)). Both TS and Python now share the same journal table. Override the name viaCHKIT_JOURNAL_TABLE. - Checksum mismatch detection in
status,check, andmigrate: re-hashes each.sqlfile and compares against the checksum recorded in the journal. Mismatches block applies. chkit check --strictflag matches TS: enables every policy (failOnPending,failOnChecksumMismatch,failOnDrift) regardless of config. Exit code 1 when any policy fails.safe_name,safe_migration_id,checksum_sqlpublic helpers inchkit.cli.migration_store.
- Snapshot file ends with a trailing newline (
json + "\n"), matching the TS write. statusoutput text matches TS verbatim:Database-missing warning ("Database X does not exist on the target server") reproduced verbatim.Migrations directory: <dir> Total migrations: <N> Applied: <N> Pending: <N>pending_migrationsand the journal now key by filename (with.sql), matching the TSMigrationJournalEntry.name. Pre-0.1.3 keys (stem-only) inmeta/applied.jsonare no longer compatible; if you had an offlineapplied.json, either delete it or re-apply viachkit migrate --applyto populate the new ClickHouse journal.chkit inittemplate prompts users to runchkit generate --name initfollowed bychkit migrate --apply(was--label init+migrate).
The journal moved from meta/applied.json to the ClickHouse _chkit_migrations
table. To migrate an existing project:
- Run
chkit migrate --apply. Already-applied migrations will fail with "table already exists"; the journal will not record them. - Recommended: clear the old
applied.jsononce the ClickHouse journal is the source of truth.
If you need to manually seed the journal from a applied.json, insert rows
into _chkit_migrations matching the schema in
packages/cli/src/runtime/journal-store.ts.
chkit initis now a 1:1 port of the TypeScriptinitcommand:- Writes
clickhouse.config.py(matching the TSclickhouse.config.tsconvention) instead ofchkit.config.py. - Scaffolds the schema at
src/db/schema/example.py(wasschema/events.py). - The generated config exports
migrationsDir,metaDir, and apluginslist explicitly, mirroring the TS template. - ClickHouse credentials default through
os.environ.get(...)instead of being hardcoded. - Example schema columns match TS (
id/source/ingested_atwithpartitionBy: toYYYYMM(ingested_at)). - Prints the same "Next steps" message + docs link as TS.
- Removed the
--outflag; init scaffolds into the current working directory like the TS version.
- Writes
ChxUserConfignow accepts apluginslist (was silently rejected as an extra field, which brokechkit generatefor any config produced bychkit init).define_config()now accepts plain dicts in addition toChxUserConfiginstances, matching the TSdefineConfigidentity-helper signature.
- All CLI help strings now reference
clickhouse.config.py(e.g. the--configoption ingenerate,migrate,status,check,drift). load_config()default path is now./clickhouse.config.py(was./chkit.config.py). Pass--config <path>to override.
If you have an existing chkit.config.py, rename it to clickhouse.config.py
or pass --config chkit.config.py to each command. The file contents do not
need to change.
chkit checkreported every migration on disk as pending, regardless of the applied journal (meta/applied.json). It now correctly subtracts applied ids, matching the behaviour ofchkit statusandchkit drift.
chkit generateno longer writes a per-migration JSON sidecar (<id>.json) next to the.sqlfile. The TypeScript reference only emits.sql; checksums are computed on the fly when needed. If you have pre-0.1.1 projects with sidecars, you can safely delete the.jsonfiles inchkit/migrations/— they were redundant and never read.chkit.cli.migration_storenow exposes shared helpers (read_applied,write_applied,pending_migrations,checksum_sql). The duplicated private copies in thestatus,check, andmigratecommands were collapsed into the single source of truth.
- Regression test suite at
tests/test_migration_store.pycovering thecheckbug above and the helper contract.
- Initial release. 1:1 Python port of the TypeScript chkit core: schema DSL,
canonicalization, codec parser, migration planner, validation, CLI
(
init,generate,migrate,status,check,drift). - 255 ported tests from the TS suite + 7 originals all green.