Free forever·No credit card·2-min setup·EU-hostedStart free
rawquery
vsdbt
Compare · SQL transformation

rawquery vs dbt

dbt is the standard for SQL transformation in warehouses you already own. It ships tests, a docs site, packages, and a semantic layer. rawquery ships transforms too, but without YAML, Jinja, adapter config, or a second runtime. The trade: no package ecosystem, no Jinja macros, no MetricFlow. Different shape, different tier.

dbt (framework)
models/*.sql
schema.yml
dbt_project.yml
profiles.yml
Python dbt CLI
warehouse adapter

Runs against your warehouse.
(Snowflake / BigQuery / ...)

rawquery (product)
rq transforms create mrr \
  --schedule "0 2 * * *" \
  --sql "SELECT ..."

Runs where the data lives.
No YAML, no Jinja, no adapter.

TL;DR

  • Pick rawquery if you want transforms that run in the same product as ingestion, storage, and serving, with no Jinja, no YAML, no warehouse adapter config, and no per-seat pricing.
  • Pick dbt if you have an analytics engineering team that lives in git, you rely on the dbt package ecosystem, you need MetricFlow for a semantic layer, or your warehouse is Snowflake / BigQuery / Databricks and you want the dbt standard.

Feature-by-feature

Dimensionrawquerydbt
ShapeProduct (integrated)Framework on top of a warehouse
AuthoringSQL + {{ ref() }}Jinja SQL + YAML config
Required toolsCLI or web UIPython, dbt CLI, git, adapter
RuntimeIntegrated schedulerdbt Cloud / Airflow / cron
Materializationstable, view, incremental+ ephemeral, snapshot, MV
TestsScheduled SQL checksFirst-class assertion framework
DocumentationLineage DAG in UIAuto-generated docs site
Package ecosystemNonedbt Hub
Semantic layerNoneMetricFlow
PricingIncluded in plan~$100 / seat / month (dbt Cloud)

dbt is a framework. rawquery is a product.

dbt compiles SQL templates into DDL against a warehouse you already own. It assumes a lot: that you have a warehouse, adapter credentials, a git repo, a CI pipeline, and somebody who knows how to set up all of the above. In return, it gives you a rigorous model layer with tests, docs, and reusable packages. The analytics engineer's tool of choice.

rawquery's transforms are first-class objects in the same product as your data. They are not files in a repo and they do not require a second runtime. You write SQL, you give it a name, you optionally schedule it with a cron expression. References to other transforms use a single template: {{ ref('other_transform') }}. That is the full templating surface. If you want to commit the SQL to git, you can. The CLI still owns the transform object.

A transform, two ways

Same transform: monthly recurring revenue from Stripe subscriptions.

dbt: models/mrr.sql + schema.yml + dbt_project.yml
sql
-- models/mrr.sql
{{ config(materialized='incremental', unique_key='month') }}
SELECT
date_trunc('month', created_at) AS month,
sum(plan_amount) / 100.0 AS mrr
FROM {{ source('stripe', 'subscriptions') }}
WHERE status = 'active'
{% if is_incremental() %}
AND created_at > (SELECT max(month) FROM {{ this }})
{% endif %}
GROUP BY 1
rawquery: one CLI call
bash
rq transforms create mrr \
--schedule "0 2 * * *" \
--sql "SELECT
date_trunc('month', created_at) AS month,
sum(plan_amount) / 100.0 AS mrr
FROM my_stripe.subscriptions
WHERE status = 'active'
GROUP BY 1"

The dbt version is more powerful: the incremental block lets you backfill efficiently. The rawquery version is shorter and runs without installing dbt, configuring an adapter, or maintaining a repo. Both are valid. They target different people.

Where dbt still wins

  • Ecosystem. dbt Hub packages (dbt_utils, dbt_expectations, audit_helper, vendor-shipped transformations from Fivetran / Stripe / Salesforce) are a serious productivity lever. We have no package registry.
  • Testing. First-class assertions with clear semantics: unique, not_null, accepted_values, relationships, plus custom tests and generic tests. Ours are scheduled SQL checks. Less strict, more pragmatic.
  • Documentation. Auto-generated dbt docs site with column-level lineage, source metadata, and exposure tracking. Our lineage view shows the DAG; their docs site shows the model.
  • Semantic layer.MetricFlow gives you metric definitions, dimensional modeling, and a query API. We don't have one and it is not on the near-term roadmap.
  • Portability. dbt Core is Apache 2.0 and runs against any supported warehouse. If you change warehouse, your models come with you. Our transforms run on rawquery. The Iceberg tables underneath are portable; the transform definitions are not.
  • Snapshots. dbt snapshots implement slowly-changing-dimension type-2 semantics out of the box. We don't.

Try rawquery

bash
# Install the CLI
curl -sSL rawquery.dev/install.sh | sh
# Connect your source
rq connections create my-stripe --type stripe -p api_key=sk_live_xxx
rq connections sync my-stripe
# Create a transform (SQL only, no YAML)
rq transforms create active_customers \
--sql "SELECT id, email FROM my_stripe.customers WHERE status = 'active'"
# Chain transforms with {{ ref('...') }}
rq transforms create active_count \
--schedule "0 * * * *" \
--sql "SELECT count(*) FROM {{ ref('active_customers') }}"