Graph-backed assets
Basic assets are computed using a single op. If generating an asset involves multiple discrete computations, you can use graph-backed assets by separating each computation into an op and assembling them into an op graph to combine your computations. This allows you to launch re-executions of runs at the op boundaries, but doesn't require you to link each intermediate value to an asset in persistent storage.
Defining graph-backed assets
To define a graph-backed asset, use the @dg.graph_asset decorator. The decorated function defines the dependencies between a set of ops, which are combined to compute the asset.
In the example below, when you tell Dagster to materialize the slack_files_table asset, Dagster will invoke fetch_files_from_slack and then invoke store_files after fetch_files_from_slack has completed:
import pandas as pd
import dagster as dg
from dagster_slack import SlackResource
@dg.op
def fetch_files_from_slack(slack: SlackResource) -> pd.DataFrame:
files = slack.get_client().files_list(channel="#random")
return pd.DataFrame(
[
{
"id": file.get("id"),
"created": file.get("created"),
"title": file.get("title"),
"permalink": file.get("permalink"),
}
for file in files
]
)
@dg.op
def store_files(files):
return files.to_sql(name="slack_files", con=create_db_connection())
@dg.graph_asset
def slack_files_table():
return store_files(fetch_files_from_slack())
Defining managed-loading dependencies for graph-backed assets
Similar to single-op asset definitions, Dagster infers the upstream assets from the names of the arguments to the decorated function. Dagster will then delegate loading the data to an I/O manager.
The example below includes an asset named middle_asset. middle_asset depends on upstream_asset, and downstream_asset depends on middle_asset:
import dagster as dg
@dg.asset
def upstream_asset():
return 1
@dg.op
def add_one(input_num):
return input_num + 1
@dg.op
def multiply_by_two(input_num):
return input_num * 2
@dg.graph_asset
def middle_asset(upstream_asset):
return multiply_by_two(add_one(upstream_asset))
@dg.asset
def downstream_asset(middle_asset):
return middle_asset + 7
Graph-backed multi-assets
Using the @dg.graph_multi_asset, you can create a combined definition of multiple assets that are computed using the same graph of ops and same upstream assets.
In the below example, two_assets accepts upstream_asset and outputs two assets, first_asset and second_asset:
import dagster as dg
@dg.graph_multi_asset(
outs={"first_asset": dg.AssetOut(), "second_asset": dg.AssetOut()}
)
def two_assets(upstream_asset):
one, two = two_outputs(upstream_asset)
return {"first_asset": one, "second_asset": two}