Skip to main content

quickdbd-cli (qdbd)

Compile QuickDBD-syntax schema files into interactive HTML ER diagrams, with no table limit, from the command line. Built to stay readable at 200+ tables.

Customer
-
CustomerId PK int
Name string

Order
-
OrderId PK int
CustomerId int FK >- Customer.CustomerId
pipx install quickdbd-cli        # or: uvx --from quickdbd-cli qdbd ...
qdbd build schema.txt -o schema.html

Docs: https://markphamm.github.io/quickdbd-cli/ · Live demo (200 tables): https://markphamm.github.io/quickdbd-cli/demo/

Not affiliated with QuickDBD. It reads the same text syntax, so schemas move freely between the two.

Features

  • Same syntax as QuickDBD: tables, aliases, quoted names, all 9 relationship operators, rel lines, PK/FK/NULL/UNIQUE/INDEX/IDENTITY, default=, doc comments, [settings] and [layout] sections. Error messages are QuickDBD's own.
  • Interactive page:
    • explorer sidebar: tables grouped by file or dbt folder, with search (/, Enter jumps to the best match)
    • table detail panel (dbt-docs style, for relationships): description, columns with type/keys/docs, and clickable References / Referenced by lists
    • minimap
    • click a table to focus on it and its neighbours
    • collapse tables: full / keys only / names only
    • hover a column to highlight its relationship
    • hover a dotted-underlined table or column to read its # doc comments
    • PNG/SVG export buttons, and draw.io: an editable diagrams.net file using draw.io's ER table shapes and crow's-foot arrows
    • Path finder: in a table's detail panel, type another table to see the shortest join path, highlighted on the canvas, with a ready-to-paste SQL JOIN (also qdbd path erd/ --from payments --to customers)
    • Regions: a shaded, labelled area per file or dbt folder (toolbar toggle). --by-group on build / export / layout arranges tables so each folder sits together
    • shareable links: the URL keeps the filter, selected table, collapse mode and zoom; Link copies it
  • Live editing: qdbd serve reloads when you save, has a browser editor pane with autosave, and remembers where you drag tables.
  • Many files, one diagram: point it at a folder and foreign keys can cross files.
  • Pip-only install: no Graphviz, Node or browser needed. Layout uses ELK, running in an embedded V8.
  • CI-friendly: builds are deterministic, and errors are file:line: error: … with exit code 1.

From a dbt project

dbt docs generate                                   # optional: adds real column types (catalog.json)
qdbd import dbt target/manifest.json -o erd/        # one .txt per folder (staging, marts, sources, ...)
qdbd build erd/ -o erd.html
  • Tables: models, seeds and snapshots of your project, plus sources.
  • Relationships: relationships tests (including dbt_utils relationships_where) and foreign_key constraints.
  • Primary keys: primary_key constraints, or else a column with both unique and not_null tests.
  • Docs: model and column descriptions become doc comments, shown as tooltips.
  • --infer-fks: also links customer_id-style columns to the table they name, when no relationship is declared. Ambiguous matches are skipped, never guessed.
  • --check: in CI, fails when the committed files are out of date.
  • Options:
    • --select 'marts.*' narrows by name, fqn or path (repeatable)
    • --package all includes installed packages
    • --no-sources drops sources
    • -o schema.txt writes a single file

Re-running the import overwrites the generated files. Table positions survive because they live in the layout file, keyed by table name.

Selecting tables

Like dbt's --select, but it follows relationships instead of lineage. It works in the page's filter box and as -s/--select / --exclude on build and export.

Selector Tables
orders / stg_* by name or alias (glob, case-insensitive)
+orders orders and every table it references (any depth); 1+orders limits to one hop
orders+ orders and every table that references it; orders+2 limits to two hops
+orders+1 both directions
group:marts a file or dbt folder (and its subfolders)
file:core.txt a schema file (glob)
col:customer_id tables with a matching column
diff:modified / diff:added / diff:changed changed since --diff-base (like dbt state:modified)
a b / a,b / !a union / intersection / exclude
qdbd build erd/ -s 'group:marts' --exclude '*_tmp' -o marts.html
qdbd export erd/ -s '+orders+1' -o orders.png

Schema diffs

qdbd diff old.txt new.txt                         # two versions
qdbd diff --base origin/main erd/                 # git ref vs working tree
qdbd diff --base origin/main erd/ --format markdown -o diff.md   # for a PR comment
qdbd build erd/ --diff-base origin/main -o erd.html              # colour what changed

diff reports tables added and removed, column changes (added, removed, type and flag changes) and relationships added and removed. --format json is available, and --exit-code exits 1 when anything changed.

With --diff-base, the page:

  • marks new tables green and changed tables amber, with a bar on each changed column;
  • shows a summary banner, and its Show changes link filters to the changes plus their neighbours;
  • lists each table's changes in the detail panel.

The selector diff:modified (or diff:added / diff:changed) works like dbt's state:modified, e.g. -s 'diff:modified+1'.

Commands

qdbd check  PATH... [--strict]                 # validate; "No errors found. Good job!"
qdbd build  PATH... -o diagram.html            # shareable interactive HTML
qdbd serve  PATH... [--port 8765]              # live editor + drag-to-arrange
qdbd export PATH... -o out.png [--focus Customer --depth 1]   # PNG, SVG or .drawio
qdbd layout PATH... [--reset]                  # (re)write the layout file
qdbd import dbt target/manifest.json -o erd/   # generate schema files from a dbt project
qdbd path PATH... --from A --to B              # shortest join path + SQL JOIN snippet

PATH is a .txt file or a folder. Every *.txt under a folder is read recursively.

Table positions

The first build auto-arranges the tables. In qdbd serve, drag tables where you want them. Positions are saved to a sidecar file you can commit:

  • schema.txt → schema.layout.json
  • a folder → <folder>/qdbd.layout.json
  • override either with --layout FILE

Once a layout exists, a new table is placed next to the tables it's related to, and nothing else moves. Run qdbd layout PATH --reset to re-arrange everything from scratch. A pasted schema's QuickDBD [layout] section is used for any table the sidecar doesn't cover.

qdbd build never writes the sidecar, so CI builds leave the working tree clean.

Differences from QuickDBD

qdbd accepts a few things QuickDBD rejects, and prints a warning for each one:

  • tab characters
  • decimal(10, 2) (a space inside a type)
  • an explicit NOT NULL
  • indented table names
  • [layout] entries for unknown tables

qdbd check --strict turns these warnings into errors, so a file that passes is guaranteed to paste into QuickDBD.

default= values keep their case, where QuickDBD lowercases them.

CI

GitHub Action: checks the schema and builds the diagram. On pull requests it also posts one schema-diff comment, updated on every push, and highlights the changes in the diagram artifact.

name: ERD
on: [pull_request, push]
jobs:
  erd:
    runs-on: ubuntu-latest
    permissions: { contents: read, pull-requests: write }
    steps:
      - uses: actions/checkout@v4
      - uses: MarkPhamm/quickdbd-cli@v0.1.6
        with:
          path: erd/                 # schema file(s) or folder(s)
          output: site/index.html
Input Default
path (required) schema files or folders
output erd/index.html HTML diagram path
check / strict true / false fail on errors / also on QuickDBD-compatibility warnings
comment true post the diff comment on PRs
select dbt-style selector for the diagram
qdbd-version latest PyPI version

Outputs are html, changed and diff-file.

Publishing: to publish the diagram on GitHub Pages, add actions/upload-pages-artifact + actions/deploy-pages after it. See .github/workflows/erd.yml, which publishes this repo's demo.

pre-commit:

repos:
  - repo: https://github.com/MarkPhamm/quickdbd-cli
    rev: v0.1.6
    hooks:
      - id: qdbd-check
        files: ^erd/.*\.txt$   # point at your schema files

GitLab CI:

erd:
  image: python:3.12
  script:
    - pip install quickdbd-cli
    - qdbd check erd/
    - qdbd build erd/ -o public/index.html
  artifacts:
    paths: [public/index.html]

Development

uv venv && uv pip install -e ".[dev]"
.venv/bin/pytest
python scripts/gen_schema.py        # regenerate examples/synthetic (200 tables)
python scripts/gen_font_metrics.py  # regenerate font width table

Design notes: docs/superpowers/specs/2026-10-17-qdbd-design.md.

Releasing

Put PyPI credentials in .env (gitignored):

TWINE_USERNAME=__token__
TWINE_PASSWORD=pypi-...

Bump version in pyproject.toml and src/quickdbd_cli/__init__.py, commit, then run PATH="$PWD/.venv/bin:$PATH" scripts/release.sh. It builds, uploads to PyPI, tags vX.Y.Z and creates the GitHub release.

License

Apache-2.0. Bundled third-party files are listed in NOTICE.

Metadata

Release files for quickdbd-cli 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for quickdbd-cli 0.1.6
File Size Uploaded Provenance
quickdbd_cli-0.1.6.tar.gz 1.2 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for quickdbd-cli 0.1.6
File Interpreter ABI Platform
quickdbd_cli-0.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 2.4 MB

Release files / quickdbd_cli-0.1.6.tar.gz

Download URL quickdbd_cli-0.1.6.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
6bd18c2b262a8becbeb7e01968f274cb466ff9347721d1cb556272dc290cf67d
BLAKE2b-256 checksum
How to use checksums
09afa215eafd5dc5cc114c53f57255cbd7aca27e0dab2f137186e332ce49024b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / quickdbd_cli-0.1.6-py3-none-any.whl

Download URL quickdbd_cli-0.1.6-py3-none-any.whl
Size 1.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
d676a0969ab1d93e60f44c2e4b74dd3900f071bc061f3c25fd48370b418d4b35
BLAKE2b-256 checksum
How to use checksums
9141bdc49804b62cbca48f227fe51bd438d92058bf2fcb9bcdd2d5e4751eaa12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Security for quickdbd-cli 0.1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page