DataLane
← All cheat sheets

Dagster cheat sheet

Software-defined assets, resources, partitions, and sensors — the Dagster model that differs most from Airflow.

Orchestration & ToolsIntermediate6 sections

Assets, not tasks

@asset def orders_raw() -> pd.DataFrame: return pd.read_parquet("s3://lake/bronze/orders/")
An asset declares the table it produces, not a step to run. Dagster derives the graph from what each asset depends on.
@asset def orders_enriched(orders_raw, customers): return orders_raw.merge(customers, on="customer_id")
Dependencies come from parameter names. No explicit set_upstream wiring anywhere in the project.
@asset(key_prefix=["silver"], group_name="orders")
Namespacing and grouping. Key prefixes become schema paths in the asset lineage view.
AssetOut / @multi_asset
For one computation that writes several tables — a common ELT shape that Airflow forces into artificial task splits.

Resources and config

@asset def orders(snowflake: SnowflakeResource): with snowflake.get_connection() as conn: ...
Resources are injected by type annotation, which makes swapping a real warehouse for a fake in tests trivial.
defs = Definitions(assets=[...], resources={"snowflake": SnowflakeResource(...)})
The single entry point Dagster loads. Environment differences live here, not scattered through asset code.
EnvVar("SNOWFLAKE_PASSWORD")
Late-bound secret resolution — the value is read at run time, so it never lands in a serialized definition.

Partitions and backfills

@asset(partitions_def=DailyPartitionsDefinition(start_date="2026-01-01"))
Declares the asset as one row of data per day. Backfilling becomes selecting a partition range in the UI.
context.partition_key
How the asset body learns which date it is computing. The equivalent of Airflow's data_interval_start.
MultiPartitionsDefinition
Two-dimensional partitions, such as date crossed with region. Useful and easy to overuse — the cross product grows fast.

Schedules and sensors

build_schedule_from_partitioned_job(job)
Derives the cron from the partition definition so schedule and partitioning can never drift apart.
@sensor(job=my_job) def new_file_sensor(context): if new_files(): yield RunRequest(run_key=...)
Event-driven triggering. run_key provides deduplication so the same file cannot launch two runs.
@asset_sensor(asset_key=AssetKey("orders_raw"))
Fires when an upstream asset materializes — cross-project dependencies without a shared scheduler.
AutoMaterializePolicy.eager()
Declarative freshness. Dagster decides when to rebuild based on upstream changes instead of a fixed cron.

dbt integration

@dbt_assets(manifest=dbt_manifest_path)
Loads every dbt model as an individual Dagster asset, so lineage spans ingestion and transformation in one graph.
dbt.cli(["build"], context=context).stream()
Streams dbt events into Dagster logs, marking each model asset materialized as it completes.

Testing and CLI

materialize([orders_raw, orders_enriched])
Runs assets in-process from a pytest function — the main practical advantage over testing Airflow DAGs.
dagster dev
Local UI plus daemon in one command. The default development loop.
dagster asset materialize --select orders_enriched
CLI materialization with the same selection syntax the UI uses.

From DataLane — tutorials at/blog, practice SQL live in theplayground.

↑↓ navigate openesc close