Skip to main content

Dagster & Tableau (Component)

Beta feature

This feature is considered in a beta stage. It is still being tested and may change. For more information, see the API lifecycle stages documentation.

The dagster-tableau library provides a TableauComponent which can be used to easily represent Tableau workbooks, sheets, dashboards, and data sources as assets in Dagster.

info

TableauComponent is a state-backed component, which fetches and caches Tableau workspace metadata. For information on managing component state, see Configuring state-backed components.

1. Prepare a Dagster project

To begin, you'll need a Dagster project. You can use an existing components-ready project or create a new one:

uvx create-dagster project my-project && cd my-project/src

Activate the project virtual environment:

source ../.venv/bin/activate

Finally, add the dagster-tableau library to the project:

uv add dagster-tableau

2. Scaffold a Tableau component definition

Now that you have a Dagster project, you can scaffold a Tableau component definition:

dg scaffold defs dagster_tableau.TableauComponent tableau_ingest
Creating defs at /.../my-project/src/my_project/defs/tableau_ingest.

The dg scaffold defs call will generate a defs.yaml file:

tree my_project/defs
my_project/defs
├── __init__.py
└── tableau_ingest
└── defs.yaml

2 directories, 2 files

3. Configure your Tableau workspace

Update the defs.yaml file with your Tableau workspace connection details. You'll need to provide your connected app credentials and site information. For more information on creating a connected app, see the Tableau documentation.

The configuration depends on whether you're using Tableau Cloud or Tableau Server:

For Tableau Cloud, set type: cloud and provide your pod_name:

my_project/defs/tableau_ingest/defs.yaml
type: dagster_tableau.TableauComponent

attributes:
workspace:
type: cloud
connected_app_client_id: "{{ env.TABLEAU_CONNECTED_APP_CLIENT_ID }}"
connected_app_secret_id: "{{ env.TABLEAU_CONNECTED_APP_SECRET_ID }}"
connected_app_secret_value: "{{ env.TABLEAU_CONNECTED_APP_SECRET_VALUE }}"
username: "{{ env.TABLEAU_USERNAME }}"
site_name: "{{ env.TABLEAU_SITE_NAME }}"
pod_name: "{{ env.TABLEAU_POD_NAME }}"
dg list defs
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Section ┃ Definitions ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Assets │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓ │
│ │ ┃ Key ┃ Group ┃ Deps ┃ Kinds ┃ Description ┃ │
│ │ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩ │
│ │ │ superstore_datasource │ default │ │ live │ │ │
│ │ │ │ │ │ published datasource │ │ │
│ │ │ │ │ │ tableau │ │ │
│ │ ├─────────────────────────────────────────┼─────────┼──────┼──────────────────────┼─────────────┤ │
│ │ │ test_workbook/dashboard/dashboard_sales │ default │ │ dashboard │ │ │
│ │ │ │ │ │ tableau │ │ │
│ │ ├─────────────────────────────────────────┼─────────┼──────┼──────────────────────┼─────────────┤ │
│ │ │ test_workbook/sheet/sales │ default │ │ sheet │ │ │
│ │ │ │ │ │ tableau │ │ │
│ │ └─────────────────────────────────────────┴─────────┴──────┴──────────────────────┴─────────────┘ │
└─────────┴───────────────────────────────────────────────────────────────────────────────────────────────────┘

4. Enable data source refresh

You can enable refreshing data sources by adding the enable_published_datasource_refresh or enable_embedded_datasource_refresh keys. To enable refresh for all data sources of a given type, set the value to True:

type: dagster_tableau.TableauComponent

attributes:
workspace:
type: cloud
connected_app_client_id: '{{ env.TABLEAU_CLIENT_ID }}'
connected_app_secret_id: '{{ env.TABLEAU_SECRET_ID }}'
connected_app_secret_value: '{{ env.TABLEAU_SECRET_VALUE }}'
username: '{{ env.TABLEAU_USERNAME }}'
site_name: my_site
pod_name: my_pod
enable_published_datasource_refresh: true
enable_embedded_datasource_refresh: true

To enable refreshing specific published data sources, set enable_published_datasource_refresh to a list of published data source names or ids. To enable refreshing embedded data sources for specific workbooks, set enable_embedded_datasource_refresh to a list of workbook names or ids:

type: dagster_tableau.TableauComponent

attributes:
workspace:
type: cloud
connected_app_client_id: '{{ env.TABLEAU_CLIENT_ID }}'
connected_app_secret_id: '{{ env.TABLEAU_SECRET_ID }}'
connected_app_secret_value: '{{ env.TABLEAU_SECRET_VALUE }}'
username: '{{ env.TABLEAU_USERNAME }}'
site_name: my_site
pod_name: my_pod
enable_published_datasource_refresh:
- sales_data
- marketing_data
enable_embedded_datasource_refresh:
- sales_workbook
- marketing_workbook
note

Only data sources with extracts can be refreshed. For more information, see Refreshing Data Sources in the Tableau documentation.

5. Customize Tableau asset metadata

You can customize the metadata and grouping of Tableau assets using the translation key:

my_project/defs/tableau_ingest/defs.yaml
type: dagster_tableau.TableauComponent

attributes:
workspace:
type: cloud
connected_app_client_id: "{{ env.TABLEAU_CONNECTED_APP_CLIENT_ID }}"
connected_app_secret_id: "{{ env.TABLEAU_CONNECTED_APP_SECRET_ID }}"
connected_app_secret_value: "{{ env.TABLEAU_CONNECTED_APP_SECRET_VALUE }}"
username: "{{ env.TABLEAU_USERNAME }}"
site_name: "{{ env.TABLEAU_SITE_NAME }}"
pod_name: "{{ env.TABLEAU_POD_NAME }}"
translation:
group_name: tableau_data
description: "Tableau {{ data.content_type.value }}: {{ data.properties.name }}"
dg list defs
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Section ┃ Definitions ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Assets │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ │
│ │ ┃ Key ┃ Group ┃ Deps ┃ Kinds ┃ Description ┃ │
│ │ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩ │
│ │ │ superstore_datasource │ tableau_data │ │ live │ Tableau │ │
│ │ │ │ │ │ published │ data_source: │ │
│ │ │ │ │ │ datasource │ superstore_datas… │ │
│ │ │ │ │ │ tableau │ │ │
│ │ ├─────────────────────────────────────────┼──────────────┼──────┼────────────────────┼───────────────────┤ │
│ │ │ test_workbook/dashboard/dashboard_sales │ tableau_data │ │ dashboard │ Tableau │ │
│ │ │ │ │ │ tableau │ dashboard: │ │
│ │ │ │ │ │ │ dashboard_sales │ │
│ │ ├─────────────────────────────────────────┼──────────────┼──────┼────────────────────┼───────────────────┤ │
│ │ │ test_workbook/sheet/sales │ tableau_data │ │ sheet │ Tableau sheet: │ │
│ │ │ │ │ │ tableau │ sales │ │
│ │ └─────────────────────────────────────────┴──────────────┴──────┴────────────────────┴───────────────────┘ │
└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Customize specific data types

You may also specify distinct translation behavior for specific data types. For example, you can add a tag to all sheets:

my_project/defs/tableau_ingest/defs.yaml
type: dagster_tableau.TableauComponent

attributes:
workspace:
type: cloud
connected_app_client_id: "{{ env.TABLEAU_CONNECTED_APP_CLIENT_ID }}"
connected_app_secret_id: "{{ env.TABLEAU_CONNECTED_APP_SECRET_ID }}"
connected_app_secret_value: "{{ env.TABLEAU_CONNECTED_APP_SECRET_VALUE }}"
username: "{{ env.TABLEAU_USERNAME }}"
site_name: "{{ env.TABLEAU_SITE_NAME }}"
pod_name: "{{ env.TABLEAU_POD_NAME }}"
translation:
for_sheet:
tags:
is_sheet: "true"
dg list defs --columns name,kinds,tags
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Section ┃ Definitions ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Assets │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ │
│ │ ┃ Key ┃ Kinds ┃ Tags ┃ │
│ │ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │
│ │ │ superstore_datasource │ live │ "dagster-tableau/asset_type"="data_s… │ │
│ │ │ │ published datasource │ "dagster/storage_kind"="tableau" │ │
│ │ │ │ tableau │ │ │
│ │ ├─────────────────────────────────────────┼──────────────────────┼───────────────────────────────────────┤ │
│ │ │ test_workbook/dashboard/dashboard_sales │ dashboard │ "dagster-tableau/asset_type"="dashbo… │ │
│ │ │ │ tableau │ "dagster/storage_kind"="tableau" │ │
│ │ ├─────────────────────────────────────────┼──────────────────────┼───────────────────────────────────────┤ │
│ │ │ test_workbook/sheet/sales │ sheet │ "dagster-tableau/asset_type"="sheet" │ │
│ │ │ │ tableau │ "dagster/storage_kind"="tableau" │ │
│ │ │ │ │ "is_sheet"="true" │ │
│ │ └─────────────────────────────────────────┴──────────────────────┴───────────────────────────────────────┘ │
└─────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────┘