Skip to main content

dbt Support

Querylab.io natively supports dbt Jinja SQL. Write and test dbt models directly in the editor with full completions, diagnostics, compiled preview, and mapping management — no dbt CLI required.


Getting Started

dbt mode activates automatically when Querylab.io detects Jinja patterns in your SQL:

  • {{ ... }} Jinja expressions
  • {% ... %} Jinja blocks
  • {# ... #} Jinja comments
  • -- dbt:* directive comments

Paste any dbt model SQL into the editor and the dbt panel appears automatically.

Enable/Disable

dbt mode is enabled by default. To toggle it:

Settings > SQL Frameworks > Enable dbt Mode

See Settings for all dbt-related settings.


The dbt Panel

When dbt mode activates, a dbt button appears in the status bar at the bottom of the editor. Click it to open the dbt panel on the right side.

  • Left-click the status bar button to toggle the panel
  • Right-click the button to deactivate dbt mode for this tab

The panel has six sections:

Active Directives

Lists all dbt directives found in your SQL. Each shows the directive call and its resolution status:

  • Resolved: Shows the mapped BigQuery table (e.g., project.dataset.users)
  • Unresolved: Shows "Unresolved — add mapping" — click to add a mapping

Hover over a directive to edit or delete it.

Detected Tables

Tables from your FROM and JOIN clauses that are not yet converted to dbt refs. Click Convert to dbt ref to replace the table reference with {{ ref('model_name') }}.

Detected Values

String literal values in your SQL that could be extracted as dbt variables. Click Convert to dbt var to replace the value with {{ var('variable_name') }}.

Table Mappings

Manage your ref() and source() mappings. Each mapping connects a dbt model or source name to its BigQuery table.

  • Add new mappings with the Add new mapping form
  • Search mappings when you have 5 or more
  • Remove unused clears mappings not referenced in the current SQL

Mappings are saved globally and reused across tabs.

Variable Mappings

Manage your var() mappings. Each maps a variable name to its resolved value.

Macro Definitions

Define and manage reusable SQL macros. Each macro has a name, parameter list, and body.

  • Add macros with the Add macro form — specify name, parameters (comma-separated, e.g., col, precision=2), and SQL body
  • Parameters with = are optional and use the value after = as the default
  • Edit macro bodies inline with the multiline editor
  • A green dot indicates the macro is used in the current SQL; gray means unused
  • Search macros when you have 5 or more
  • Remove unused clears macros not referenced in the current SQL

Macros can come from three sources:

  • Inline: Define {% macro name(params) %}...{% endmacro %} directly in your SQL — these are extracted automatically and take precedence
  • Manual: Add via the panel form
  • Manifest: Import from manifest.json (see Import Manifest)

Options

OptionDescription
Incremental modeWhen enabled, {% if is_incremental() %} blocks are kept during preprocessing. When disabled, they are stripped.
Auto-apply saved mappingsAutomatically resolve {{ ref() }} and {{ var() }} using your saved mappings.

Directives

Directives are SQL comments that configure dbt mappings inline. They travel with your SQL and are the primary way to define mappings.

-- dbt:ref('users') = my_project.analytics.users
-- dbt:ref('orders') = my_project.analytics.orders
-- dbt:source('raw', 'events') = my_project.raw_data.events
-- dbt:var('start_date') = 2024-01-01
-- dbt:project = my_project
-- dbt:dataset = analytics
-- dbt:model = daily_users

SELECT *
FROM {{ ref('users') }} u
JOIN {{ ref('orders') }} o ON u.id = o.user_id
WHERE o.created_at >= '{{ var("start_date") }}'

Directive Types

DirectivePurpose
-- dbt:ref('name')Declare a ref (unresolved)
-- dbt:ref('name') = project.dataset.tableDeclare a ref with resolution
-- dbt:source('schema', 'table')Declare a source
-- dbt:source('schema', 'table') = project.dataset.tableDeclare a source with resolution
-- dbt:var('name')Declare a variable (unresolved)
-- dbt:var('name') = valueDeclare a variable with value
-- dbt:project = nameSet project for {{ this }} resolution
-- dbt:dataset = nameSet dataset for {{ this }} resolution
-- dbt:model = nameSet model name for {{ this }} resolution

Inline directive resolutions (with =) take precedence over global mappings.


Compiled View

Click View compiled SQL in the panel header to preview the fully resolved BigQuery SQL.

The compiled view:

  1. Expands all {{ macro_name() }} calls using their defined bodies
  2. Resolves all {{ ref() }}, {{ source() }}, and {{ var() }} to their mapped values
  3. Handles {% if is_incremental() %} blocks based on the incremental mode toggle
  4. Strips Jinja comments ({# ... #})
  5. Shows the final SQL that would run against BigQuery

Macro expansion happens first, so macros that produce ref() or var() calls are resolved correctly.

The editor becomes read-only in compiled view. Click View source SQL to switch back.


Inlay Hints

When enabled, resolved values appear inline after Jinja expressions as faded annotations:

SELECT *
FROM {{ ref('users') }} -- → my_project.analytics.users
WHERE date >= '{{ var("start_date") }}' -- → 2024-01-01

Toggle in Settings > SQL Frameworks > dbt > Inlay Hints.


Completions

Inside Jinja expressions, Querylab.io provides context-aware completions:

  • Inside {{ }}: Suggests ref, source, var, config, this, is_incremental, and your defined macros
  • Inside {{ ref(' }}: Suggests known model names from your mappings
  • Inside {{ source('schema', ' }}: Suggests table names for that source
  • Inside {% %}: Suggests Jinja keywords (if, endif, for, endfor, etc.)

Macro completions insert snippet placeholders for each parameter. Required parameters get tab stops; optional parameters show pre-filled defaults.


Diagnostics

Querylab.io flags dbt issues with editor squiggles:

  • Unresolved ref: {{ ref('unknown_model') }} — warning with quick fix to add mapping
  • Unresolved source: {{ source('unknown', 'table') }} — warning
  • Unresolved var: {{ var('unknown') }} — warning
  • Malformed patterns: {{ ref( }} — error
  • Wrong argument count: {{ my_macro(a, b, c) }} when the macro expects fewer — warning showing expected vs actual count

Known macro names are recognized and do not trigger "unknown function" warnings.

Click the lightbulb or press Cmd/Ctrl+. to access quick fixes.


Macros

Querylab.io supports dbt macros — reusable SQL snippets with parameters that expand at compile time.

Defining Macros

Inline in SQL:

{% macro cents_to_dollars(column_name, precision=2) %}
ROUND({{ column_name }} / 100, {{ precision }})
{% endmacro %}

SELECT
{{ cents_to_dollars('amount') }} AS amount_dollars,
{{ cents_to_dollars('tax', 4) }} AS tax_dollars
FROM {{ ref('transactions') }}

Via the panel: Open the Macro Definitions section and use the Add macro form.

From manifest.json: Import your project's macros from target/manifest.json (see Import Manifest).

How Expansion Works

Macro calls are expanded before ref/source/var resolution. When compiled, the example above becomes:

SELECT
ROUND(amount / 100, 2) AS amount_dollars,
ROUND(tax / 100, 4) AS tax_dollars
FROM my_project.analytics.transactions

Nested macro calls are supported up to 10 levels deep. Built-in dbt functions (ref, source, var, config, this, is_incremental) are never treated as macro calls.


Hover

Hover over any Jinja expression to see contextual information:

  • {{ ref('model') }} — Shows the resolved table and mapping source
  • {{ macro_name() }} — Shows the macro's parameter signature, source (inline/manifest/manual), and a preview of the macro body
  • {% if %}, {% for %} — Shows a description of the Jinja block

Import Manifest

Bulk-import mappings and macros from your dbt project's manifest.json:

  1. Click the Import button (upload icon) in the panel header
  2. Paste the contents of your target/manifest.json file
  3. Review the preview showing counts of models, sources, variables, and macros
  4. Choose Merge (add to existing mappings) or Replace (overwrite all)

Macro imports filter out internal dbt and dbt_utils macros — only your project's custom macros are imported.


Export dbt Model

Generate a dbt model from your current SQL:

  1. Click Export dbt Model in the panel footer
  2. Set the model name (auto-filled from tab name)
  3. Choose materialization: view, table, incremental, or ephemeral
  4. Download the generated .sql file and schema.yml with inferred column types

Context Menu

Right-click in the editor when dbt mode is active for additional actions:

  • Convert to dbt ref — Replace selected table name with {{ ref('...') }}
  • Convert to dbt var — Replace selected value with {{ var('...') }}

Keyboard Shortcuts

ActionShortcut
Toggle dbt panelCmd/Ctrl+Shift+B