Skip to main content

dbt selectors with DbtProjectComponent

DbtProjectComponent does not directly accept dbt selectors through a dedicated selector parameter as of Dagster 1.12.0. The @dbt_assets decorator does support selectors. This guide covers four workarounds for DbtProjectComponent, plus related patterns for cross-code-location dependencies and column lineage.

Workarounds for selector support

When you need full dbt selector support, use the @dagster_dbt.dbt_assets decorator instead of the component:

src/<project_name>/defs/dbt_assets.py
@dbt_assets(
manifest=dbt_manifest_path,
selector="my_selector_name", # Native selector support
)
def my_dbt_assets(context: dg.AssetExecutionContext, dbt: DbtCliResource):
yield from dbt.cli(["build"], context=context).stream()

2. Use select and exclude with tags

DbtProjectComponent accepts select and exclude filters that mirror dbt's selection syntax. Tags work directly:

# defs.yaml
type: dagster_dbt.DbtProjectComponent
attributes:
project:
project_dir: '{{ project_root }}/path/to/dbt_project'
select: 'tag:my_tag'
exclude: 'tag:exclude_tag'

3. Reference a dbt selector by tag

If you have a richer selector defined in selectors.yml, give the underlying models a tag and reference that tag from the component. The component does not read selectors.yml directly, but tag-based selection achieves equivalent results:

# selectors.yml in your dbt project
selectors:
- name: my_business_logic
description: 'Core business models'
definition:
method: tag
value: business_core
children: true
type: dagster_dbt.DbtProjectComponent
attributes:
project:
project_dir: '{{ project_root }}/dbt_project'
select: 'tag:business_core'

4. Path-based selection

For directory-driven layouts (marts, staging, intermediate), select by path:

type: dagster_dbt.DbtProjectComponent
attributes:
project:
project_dir: '{{ project_root }}/dbt_project'
select: 'path:models/marts/'
exclude: 'path:models/staging/'

Cross-code-location dependencies

You can wire non-dbt assets in one code location into DbtProjectComponent assets in another by matching asset keys.

Step 1: Define the upstream ingestion asset:

src/<project_name>/defs/ingestion.py
@dg.asset(key_prefix=["my_ingestion"])
def my_table():
# API ingestion logic
return fetch_data()

Step 2: Declare the asset key on the dbt source:

# sources.yml in your dbt project
sources:
- name: my_ingestion
tables:
- name: my_table
meta:
dagster:
asset_key: ['my_ingestion', 'my_table']

Step 3: Reference the source in your dbt model:

-- models/my_model.sql
select * from {{ source('my_ingestion', 'my_table') }}

Dagster establishes the dependency automatically based on the matching asset key, even though the upstream asset and the dbt model live in different code locations.

Column lineage

Enable column metadata on the component to surface column-level lineage in Dagster+:

type: dagster_dbt.DbtProjectComponent
attributes:
project:
project_dir: '{{ project_root }}/dbt_project'
include_metadata:
- column_metadata # Available in Dagster 1.11.13+
note

Column lineage appears after the dbt assets are materialized, not immediately on definition load.

Choosing between approaches

Use caseRecommendationReason
Native dbt selectors@dbt_assetsFull selector support
Simple tag or path filteringDbtProjectComponentEasier configuration
Cross-location dependenciesEitherBoth work with proper source setup
Large projectsDbtProjectComponentModern approach, better performance
Complex customization@dbt_assetsMore flexibility

Roadmap

The Dagster team is closing the gap between DbtProjectComponent and @dbt_assets so the component eventually supports the full feature surface, including native selectors. Until then, the tag- and path-based approaches above provide equivalent functionality.