dbt
Author in dbt. Serve through OnlyMetrix.
omx dbt sync reads your target/manifest.json after dbt run, compiles your metric definitions through the OM IR compiler, and makes them queryable by AI agents.
Install
pip install onlymetrixThe omx CLI ships with the SDK. No separate install.
Set credentials
export OMX_API_URL=https://api.onlymetrix.com
export OMX_API_KEY=omx_sk_...Connect your warehouse
omx dbt connectReads your ~/.dbt/profiles.yml — the same credentials dbt uses — and registers the datasource with OnlyMetrix. No manual credential entry.
Reading ~/.dbt/profiles.yml
Profile: my_project | Target: dev | Type: postgres
Host: db.example.com:5432
Database: analytics
User: dbt_user
Password: ********
These credentials will be sent to OnlyMetrix to
execute metric queries against your warehouse.
Connect? [y/n] y
Connected: my_project_dev (postgres)
Run `omx dbt sync` to register your metrics.Use --profile and --target to override which profile to connect:
omx dbt connect --profile my_project --target prodEnvironment variables in profiles.yml (like {{ env_var('DBT_PASSWORD') }}) are resolved automatically from your current environment.
Sync metrics
dbt run
omx dbt syncOutput:
Synced 5 metrics (3 created, 2 updated)
Compile: 4 structured, 1 opaque, 0 failed
Tier updates: 1Your metrics are now agent-queryable. Agents call query_metric("total_revenue") and get a deterministic result.
Preview with dry-run
omx dbt sync --dry-runFound 5 metrics in manifest
total_revenue -> structured (tier: core) [create]
customer_count -> structured (tier: standard) [unchanged]
active_users -> structured (tier: standard) [update]
churn_rate -> opaque (tier: standard) [create, ratio -> splits]
ltv_estimate -> opaque (tier: standard) [create, derived]
Would sync: 3 metrics (1 structured, 2 opaque), skip 1 unchanged
Would update: 1 tierNo API calls. Shows exactly what would change.
Configure via meta
Control OnlyMetrix behavior from your dbt YAML using meta.onlymetrix:
# schema.yml
metrics:
- name: total_revenue
description: "Total paid revenue in USD"
type: simple
type_params:
measure: order_total
meta:
onlymetrix:
tier: core # core / standard / foundation
autoresearch: true # enable overnight improvement loops
scorer: revenue_corr # autoresearch scoring function| Field | Values | Default | Description |
|---|---|---|---|
tier | core, standard, foundation | standard | Controls visibility and search ranking |
autoresearch | true, false | false | Enable automated metric improvement |
scorer | scorer name | none | Which scoring function for autoresearch |
pii_columns | list of column names | [] | Flag PII columns for masking |
Tier behavior
- Core -- pinned to top of catalog, highest search rank, always visible
- Standard -- default for authored/imported metrics, shown in main catalog
- Foundation -- collapsed by default, basic aggregations. The sync never overwrites a tier you set manually in the UI.
Metric type support
| dbt type | OM compile result | What happens |
|---|---|---|
simple (sum, count, avg, min, max) | Structured | Full IR decomposition, filters + dimensions work |
count_distinct | Structured | |
ratio | Opaque | Numerator + denominator synced as separate Structured metrics |
derived | Opaque | Expression preserved, not decomposed |
| Legacy (dbt < 1.6) | Structured | type + sql + model translated to SQL template |
Ratio metrics are flagged clearly in the dry-run output:
churn_rate -> opaque (ratio -> splits into churned_count + total_subscriptions)The components (churned_count, total_subscriptions) are synced as Structured metrics that agents can query individually.
Change detection
Sync is idempotent. Each metric definition is hashed (SHA256 of name + description + SQL + tags + meta). Unchanged metrics are skipped automatically.
# First run: creates all metrics
omx dbt sync
# Synced 5 metrics (5 created, 0 updated)
# Second run: nothing changed
omx dbt sync
# All 5 metrics unchanged. Nothing to sync.
# After editing a metric description in dbt
omx dbt sync
# Synced 1 metrics (0 created, 1 updated), skip 4 unchangedHashes are stored in target/.onlymetrix_sync_state.json.
dbt test: compiles_as_structured
Validate that your metrics compile as Structured IR in your dbt test suite.
Install the dbt package
# packages.yml
packages:
- git: "https://github.com/dreynow/dbt-onlymetrix.git"
revision: maindbt depsAdd the test
# schema.yml
models:
- name: orders
columns:
- name: revenue
tests:
- onlymetrix.compiles_as_structured:
metric_name: total_revenueRun
omx dbt sync --write-status-table # writes _onlymetrix_compile_status to warehouse
dbt test # test queries the status tableThe test passes if the metric compiled as Structured. Fails if Opaque or failed. This catches compiler issues at PR time, not in production.
CI/CD
GitHub Actions
jobs:
dbt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install
run: pip install dbt-core onlymetrix
- name: dbt run
run: dbt deps && dbt run
- name: Sync metrics to OnlyMetrix
run: omx dbt sync
env:
OMX_API_URL: ${{ secrets.OMX_API_URL }}
OMX_API_KEY: ${{ secrets.OMX_API_KEY }}
- name: dbt test
run: dbt testStrict mode for CI
omx dbt sync --strictExits non-zero if any metric is opaque or failed. Use this to enforce Structured IR compilation on every PR.
CLI reference
omx dbt sync [OPTIONS]
Options:
--manifest PATH Path to manifest.json
Default: ./target/manifest.json
--project-dir PATH dbt project directory
--dry-run Preview sync without calling API
--write-status-table Write compile status to warehouse table
--strict Exit non-zero if any metric is opaque/failed
--url TEXT OnlyMetrix API URL (overrides OMX_API_URL)
--api-key TEXT API key (overrides OMX_API_KEY)How it works
omx dbt connect # reads profiles.yml, registers datasource
|
v
dbt run # your normal workflow
|
v
omx dbt sync # reads manifest.json, registers metrics
|-- parse metrics block (MetricFlow + legacy)
|-- translate type_params to SQL templates
|-- hash comparison (skip unchanged)
|-- POST /v1/metrics/sync-dbt
|
v
OM IR compiler
|-- Structured: full decomposition, filters, dimensions
|-- Opaque: SQL preserved as-is
|
v
Governed API
|
v
AI agents query deterministicallyWhat's next
- API Reference -- metric query API your agents call
- Analysis Guide -- 13 reasoning primitives on top of your metrics
- CLI Reference -- all
omxcommands - Quickstart -- five minutes from install to first finding