Skip to main content

A fast CLI tool for dbt model lineage analysis

Project description

dlin

Crates.io PyPI

dbt lineage analysis CLI that parses SQL files directly. No dbt compile, no Python, no manifest.json.

Builds a dependency graph from ref() and source() calls in SQL. Designed for AI agents and CI pipelines.

Motivation

When I edited dbt models in VS Code, dbt Power User was my go-to companion for navigating lineage. AI agents have no such companion. I watched them grep through dbt projects to find model dependencies. It works, but they end up calling grep repeatedly and relying on fragile string matching to piece together ref() and source() relationships.

dlin is designed to fill that gap: a CLI tool that lets AI agents understand a dbt project's structure without falling back to grep. It is equally useful for humans, and its stdin/stdout interface makes it easy to combine with jq, git diff, and other CLI tools.

To replace grep, speed and size matter. dlin is a small, self-contained binary with no runtime dependencies. It parses SQL directly, evaluates common Jinja patterns without Python, parallelizes file I/O, and caches aggressively.

The key idea behind dlin is that finding the right models fast is what matters most. AI agents can read SQL and trace column-level relationships on their own; the hard part is knowing which models to look at in the first place. So dlin focuses on model-level lineage and makes that as fast as possible.

Install

Cargo (Rust)

cargo install dlin

pip / uv (Python)

For convenience, dlin is also available as a Python package. The installed binary is native and does not require Python at runtime.

pip install dlin-cli   # or: uv tool install dlin-cli

GitHub Releases

Pre-built binaries for Linux, macOS, and Windows are available on the Releases page. You can also use the installer scripts:

macOS / Linux:

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/eitsupi/dlin/releases/latest/download/dlin-installer.sh | sh

Windows (PowerShell):

powershell -ExecutionPolicy Bypass -c "irm https://github.com/eitsupi/dlin/releases/latest/download/dlin-installer.ps1 | iex"

Quick start

# Full lineage graph
dlin graph -p path/to/dbt/project

# Downstream impact analysis
dlin impact orders

# List models as JSON
dlin list -o json --json-fields unique_id,file_path

# Pipe changed files into lineage
git diff --name-only main | dlin graph -o json

Features

  • No dependencies: single binary, no Python, no manifest.json
  • Recursive upstream / downstream: -u N / -d N to control traversal depth
  • Impact analysis with severity: dlin impact scores downstream nodes and flags exposure reachability
  • Composable: stdin accepts model names or file paths; pipe with jq, dlin list, git diff, etc.
  • Agent-friendly: --error-format json emits structured {"level","what","why","hint"} on stderr; --help is designed for tool discovery

Mermaid diagrams

dlin outputs Mermaid flowcharts that render natively on GitHub, GitLab, Notion, and other Markdown environments.

Simplified graphs with --collapse

Automatically remove intermediate nodes to see just the endpoints — sources, leaf models, and exposures are kept; everything in between becomes transitive "(via N)" edges:

# Collapse intermediate models — only endpoints remain
dlin graph --collapse -o mermaid
flowchart LR
    exposure_weekly_report>"weekly_report"]
    model_combined_orders["combined_orders"]
    model_order_summary["order_summary"]
    source_raw_customers(["raw.customers"])
    source_raw_orders(["raw.orders"])
    source_raw_payments(["raw.payments"])

    source_raw_customers ==>|"exposure (via 2)"| exposure_weekly_report
    source_raw_orders ==>|"exposure (via 3)"| exposure_weekly_report
    source_raw_orders -.->|"source (via 1)"| model_combined_orders
    source_raw_orders -.->|"source (via 1)"| model_order_summary
    source_raw_payments ==>|"exposure (via 3)"| exposure_weekly_report
    source_raw_payments -.->|"source (via 1)"| model_order_summary

    classDef model fill:#4A90D9,stroke:#333,color:#fff
    classDef source fill:#27AE60,stroke:#333,color:#fff
    classDef exposure fill:#E74C3C,stroke:#333,color:#fff
    class exposure_weekly_report exposure
    class model_combined_orders model
    class model_order_summary model
    class source_raw_customers source
    class source_raw_orders source
    class source_raw_payments source

Combine with --group-by to collapse per group instead of globally — for example, --collapse --group-by directory keeps the entry/exit models of each directory.

Pipe to build focused diagrams

Combine dlin list, jq, and dlin graph to extract exactly the nodes you want:

# Staging models → 1 hop downstream, models only, grouped by directory
dlin list -s 'path:models/staging' -o json | jq -r '.[].label' |
  dlin graph -d 1 --node-type model --group-by directory -o mermaid
flowchart LR
    subgraph models_marts["models/marts"]
        model_combined_orders["combined_orders"]
        model_customers["customers"]
        model_order_summary["order_summary"]
        model_orders["orders"]
    end
    subgraph models_staging["models/staging"]
        model_stg_customers["stg_customers"]
        model_stg_online_orders["stg_online_orders"]
        model_stg_orders["stg_orders"]
        model_stg_payments["stg_payments"]
        model_stg_retail_orders["stg_retail_orders"]
    end

    model_orders -->|ref| model_customers
    model_stg_customers -->|ref| model_customers
    model_stg_online_orders -->|ref| model_combined_orders
    model_stg_orders -->|ref| model_order_summary
    model_stg_orders -->|ref| model_orders
    model_stg_payments -->|ref| model_order_summary
    model_stg_payments -->|ref| model_orders
    model_stg_retail_orders -->|ref| model_combined_orders

    classDef model fill:#4A90D9,stroke:#333,color:#fff
    class model_combined_orders model
    class model_customers model
    class model_order_summary model
    class model_orders model
    class model_stg_customers model
    class model_stg_online_orders model
    class model_stg_orders model
    class model_stg_payments model
    class model_stg_retail_orders model

Column names in nodes with --show-columns

Add --show-columns to include column names inside Mermaid node labels — useful for understanding what each model produces at a glance:

dlin graph orders -u 1 -d 0 --show-columns --node-type model,source -o mermaid
flowchart LR
    model_orders["orders<br/>---<br/>order_id, customer_id, order_date, status, total_amount, payment_method"]
    model_stg_orders["stg_orders<br/>---<br/>order_id, customer_id, order_date, status"]
    model_stg_payments["stg_payments<br/>---<br/>payment_id, order_id, amount, payment_method"]

    model_stg_orders -->|ref| model_orders
    model_stg_payments -->|ref| model_orders

    classDef model fill:#4A90D9,stroke:#333,color:#fff
    class model_orders model
    class model_stg_orders model
    class model_stg_payments model

Combines well with --collapse to show rich detail on fewer endpoint nodes.

Other graph options

dlin graph orders -u 2 -d 1                            # focus on specific model
dlin graph -o mermaid --collapse --group-by node-type  # collapse per node type layer
dlin graph -o mermaid --collapse --show-columns        # columns in collapsed nodes
dlin graph -o mermaid --group-by directory             # group by directory
dlin graph -o mermaid --direction tb                   # top-to-bottom layout
dlin graph --node-type source,exposure                 # filter by node type
dlin graph -o dot | dot -Tsvg > out.svg                # Graphviz rendering

Output formats: ASCII (default), JSON, Mermaid, Graphviz DOT, Plain, SVG, HTML.

Key subcommands

list

dlin list                                                   # all models and sources
dlin list orders -o json --json-fields unique_id,file_path  # specific model as JSON
dlin list --node-type source                                # sources only

impact

$ dlin impact orders
Impact Analysis: orders
==================================================
Overall Severity: CRITICAL

Summary:
  Affected models:    1
  Affected tests:     1
  Affected exposures: 1

Impacted Nodes:
  [critical] weekly_report (exposure, distance: 1)
  [high    ] customers (model, distance: 1) [models/marts/customers.sql]
  [low     ] assert_orders_positive_amount (test, distance: 1)

Filtering

dlin graph -s tag:finance,path:marts  # selector expressions (union)
dlin graph --node-type model,source   # filter by node type

Data sources

dlin aims to work without dbt compile. By default it parses SQL files directly, but it can also leverage a pre-compiled manifest.json for additional accuracy when one is available.

SQL parsing (default): extracts ref() and source() from SQL via regex + Jinja template evaluation. No Python or dbt needed.

Manifest mode (--source manifest): reads a pre-compiled manifest.json for full accuracy with complex Jinja logic.

Limitations of SQL parse mode

  • var() resolves from dbt_project.yml only (--vars CLI overrides not supported)
  • Runtime context (target.type, env_var()) is not evaluated
  • Conditional Jinja branches use default values; non-default paths may be missed

When these limitations matter, use --source manifest.

Credits

Hard fork of dbt-lineage-viewer by Simon Muller (MIT license). The original focused on TUI-based exploration; dlin removes the TUI and targets non-interactive use: scripting, CI, and AI agents.

License

MIT

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

dlin_cli-0.1.0.tar.gz (701.9 kB view details)

Uploaded Source

Built Distributions

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

dlin_cli-0.1.0-py3-none-win_amd64.whl (2.4 MB view details)

Uploaded Python 3Windows x86-64

dlin_cli-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

dlin_cli-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

dlin_cli-0.1.0-py3-none-macosx_11_0_arm64.whl (2.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

dlin_cli-0.1.0-py3-none-macosx_10_12_x86_64.whl (2.4 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: dlin_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 701.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dlin_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b387960ee547a3c85e8dff8c702930224682e5c40f1beef995dbd2d4a0992db9
MD5 1e1785476578ec630a299528ae98e404
BLAKE2b-256 03c70658817a2cc28d75aeaf8496b859ab44652546156f30757409ed970d6091

See more details on using hashes here.

File details

Details for the file dlin_cli-0.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: dlin_cli-0.1.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 2.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dlin_cli-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 43949190b751919bfdb0d442a20005fcf939c5181540e8202279da4b44b5d3c6
MD5 3434c81efb608a5a3b78e53ddd910d37
BLAKE2b-256 74a98df76666a46f6c676dd4a9acfccf5216c5c8dd2ed5cb82ecde6f640d3abb

See more details on using hashes here.

File details

Details for the file dlin_cli-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: dlin_cli-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dlin_cli-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9b55221610dbf00d68f8092460a503e699dbc85181f110c23b12cff405606ff1
MD5 9d94737c9e245c2696034c3ed8a03a94
BLAKE2b-256 b774c109a66cbde7e7b63d1e1a058f13b9278eb1dda47af7318b0619f131e70e

See more details on using hashes here.

File details

Details for the file dlin_cli-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: dlin_cli-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dlin_cli-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 604b208c852e1c0daa238717d9de15fa202f72838f3b8ea1028c103a2c26bc5b
MD5 31eee88cb4b4c1dd9f08d3d47d46fad9
BLAKE2b-256 a9166868e30436d905252220bcb430ea24a145295a53edc7c4b5c3e51b715972

See more details on using hashes here.

File details

Details for the file dlin_cli-0.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: dlin_cli-0.1.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dlin_cli-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f891350e585b1b4f664a009107a534948e0e8b6d3d9ae460a6df83295cdebbb9
MD5 7de727782d03979a918711c4aa620aae
BLAKE2b-256 5eb90457da1335f2c6a6b35b646b7bc0ca636b3c3e8a3e086533434b82db527c

See more details on using hashes here.

File details

Details for the file dlin_cli-0.1.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: dlin_cli-0.1.0-py3-none-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 2.4 MB
  • Tags: Python 3, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dlin_cli-0.1.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 264498c5e9fa25d716f32c1537b6cd51fea980d8f263e510f3c9bdfe05359060
MD5 60b88bcfdaa9a676ecb8090f2043eca4
BLAKE2b-256 86934fad54420552ed2ac565769b4e7c81237b2f8f73d755792ce6ccda5f21fd

See more details on using hashes here.

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