Skip to main content

DDL migration and schema drift detection for DuckLake

Project description

ducktracker

Simple tool to keep your ducks in a row.

DDL migration and schema drift detection for DuckLake.

Install

pip install -e .

For development (includes pytest and ruff):

pip install -e ".[dev]"

Initialize

Create a directory and run init to scaffold the config and migrations folder:

mkdir my-ducklake
ducktracker init my-ducklake --backend ducklake-duckdb

If you omit --backend, you'll be prompted. Two options:

Backend Use when
ducklake-duckdb DuckLake catalog in a local DuckDB file. Good for local dev.
ducklake-postgres DuckLake catalog in PostgreSQL. Good for teams.

init creates ducktracker.toml, migrations/, .gitignore, and a README.md in the target directory. The directory must already exist — init won't create it.

Writing migrations

Two file types, both live in your migrations/ directory:

  • Versioned: V{n}__{description}.sql — applied once, in version order
  • Repeatable: R__{description}.sql — re-applied whenever the file content changes

Use create to scaffold the next file:

ducktracker create "create users table"
# → migrations/V2__create_users_table.sql

ducktracker create "refresh views" --repeatable
# → migrations/R__refresh_views.sql

Then open the file and add your DDL.

Running migrations

ducktracker migrate

Flags worth knowing:

--dry-run       Show what would be applied without executing any migration SQL
--target N      Only apply migrations up to version N (inclusive)

By default, checksums of previously applied versioned migrations are validated before anything runs. If a migration file has been modified after it was applied, migrate will refuse to proceed.

Checking status

ducktracker info

Prints a table with version, description, type, state, applied timestamp, and checksum for every migration it knows about. States: applied, pending, failed, outdated, missing.

To check only checksums without touching the database state:

ducktracker validate

Exits 1 if any applied migration's file has changed since it was applied.

Detecting drift

ducktracker drift

Compares the schema snapshot captured at the last migrate or baseline run against the live catalog. Exits 1 if differences are found — useful in CI to catch out-of-band schema changes.

Output shows added (+), removed (-), and modified (~) objects.

Baselining an existing database

If you're bringing an existing database under ducktracker management, use baseline before running any migrations:

ducktracker baseline --version 3
ducktracker baseline --version 3 --description "after initial setup"

This captures the current schema as a snapshot and marks the database at the given version. It will refuse to run if the history table already contains any records (including a prior baseline).

Configuration

ducktracker looks for ducktracker.toml in the current directory by default. Override with -c:

ducktracker -c path/to/ducktracker.toml migrate

A minimal config looks like this:

[connection]
catalog_name = "my_ducklake"
catalog_backend = "duckdb"
duckdb_metadata_path = "ducklake_metadata.db"

[migrations]
directory = "migrations"
target_schema = "main"

[behavior]
validate_on_migrate = true
out_of_order = false

Using a DuckDB secret

Instead of putting connection details directly in the config file, you can reference a named DuckDB persistent secret. Set secret_name in place of duckdb_metadata_path (duckdb backend) or postgres_connection (postgres backend):

[connection]
catalog_name = "my_ducklake"
catalog_backend = "postgres"
secret_name = "my_ducklake_secret"

The secret must already exist in DuckDB before ducktracker runs.

If your secrets are stored outside DuckDB's default location (~/.duckdb/stored_secrets/), add secret_directory to the same [connection] block:

[connection]
catalog_name = "my_ducklake"
catalog_backend = "postgres"
secret_name = "my_ducklake_secret"
secret_directory = "/run/secrets/duckdb"

ducktracker issues SET secret_directory before opening any catalog connection, so the path is in effect for the entire session.

Config layers

Settings are resolved in this order, with later layers winning:

  1. ducktracker.toml
  2. Environment variables
  3. CLI flags

Key environment variables

Variable Config equivalent
DUCKTRACKER_CATALOG_NAME connection.catalog_name
DUCKTRACKER_CATALOG_BACKEND connection.catalog_backend
DUCKTRACKER_DUCKDB_METADATA_PATH connection.duckdb_metadata_path
DUCKTRACKER_POSTGRES_CONNECTION connection.postgres_connection
DUCKTRACKER_SECRET_DIRECTORY connection.secret_directory

Global CLI flags

These apply to all commands except init:

-c, --config PATH       Path to ducktracker.toml
    --catalog NAME      Override catalog name
    --backend TYPE      Override backend (duckdb, postgres) — note these differ from init's backend values
    --metadata PATH     Override DuckDB metadata file path
    --connection STRING Override PostgreSQL connection string
    --secrets-dir PATH  Override DuckDB persistent secrets directory

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ducktracker-0.1.0.tar.gz (29.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ducktracker-0.1.0-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

Details for the file ducktracker-0.1.0.tar.gz.

File metadata

  • Download URL: ducktracker-0.1.0.tar.gz
  • Upload date:
  • Size: 29.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ducktracker-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c2fb093016b9d24401c8b3c7d20dff3440f619ee868565d339a67b372ca39a78
MD5 ab422aa196f5a9b777420be28f052135
BLAKE2b-256 ad13a2065dca228803ae97855988e90e52bd5dc6d7f1ad5f7c0cdadec8a77bb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for ducktracker-0.1.0.tar.gz:

Publisher: release.yml on nah-a/ducktracker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ducktracker-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ducktracker-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ducktracker-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3bfbf1664cd577c22018cc81df53a9582820f20efcf6641f5032b151fe65394b
MD5 68ef44bca657e5337856980c631fdbdb
BLAKE2b-256 229b39d30ffa8da3b0f4d8290c9a1933ae93896819c965d22dec88a1bc2f3cbb

See more details on using hashes here.

Provenance

The following attestation bundles were made for ducktracker-0.1.0-py3-none-any.whl:

Publisher: release.yml on nah-a/ducktracker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page