Metacenta

Testing · rule dagster-asset-unchecked

Dagster asset checks: how to set them up

A Dagster asset check is a test attached to an asset. It runs after the asset materialises and records a pass or a fail, so a run that wrote bad data can no longer pass unnoticed.

A Metacenta review checks this under the rule Dagster assets have an asset check. Everything below applies whether or not you ever commission one.

What an asset check does

A successful materialisation tells you the code finished. An asset check tests what the code wrote, such as a null key or a duplicated row.

How to set up an asset check

Write a function with @asset_check, name the asset it targets, and return an AssetCheckResult. Then pass the check to Definitions, or Dagster won't recognise it.

import dagster as dg
import pandas as pd

@dg.asset
def orders():
    df = pd.DataFrame({"order_id": [1, 2], "item_id": [432, 878]})
    df.to_csv("orders.csv")

@dg.asset_check(asset=orders)
def orders_id_has_no_nulls():
    df = pd.read_csv("orders.csv")
    nulls = df["order_id"].isna().sum()
    return dg.AssetCheckResult(passed=bool(nulls == 0))

defs = dg.Definitions(assets=[orders], asset_checks=[orders_id_has_no_nulls])

How to stop bad data moving downstream

By default, a failed check doesn't stop downstream assets. Set blocking=True and Dagster won't materialise them when the check fails.

@dg.asset_check(asset=orders, blocking=True)

Other ways to define a check

  • @multi_asset_check runs several checks from one function.
  • check_specs on @asset declares the check inside the asset, which then yields the result itself.
  • The dbt integration can model existing dbt tests as asset checks, so you don't have to rewrite them.

See Dagster's asset check docs for the full API.

What this rule checks

This rule flags Dagster assets with no @asset_check targeting them in the same file. When more than half the assets have none, we report it once for the project rather than once per asset.

Why it matters

A materialisation can succeed while writing wrong data, and nothing downstream is told. The run shows green, so the problem surfaces in a report rather than in Dagster.

How to fix it

Add asset checks to the Dagster assets. Add an @asset_check for each asset's grain and keys, starting with the assets people read most.

Before:

@asset
def orders(raw_orders):
    ...

After:

@asset
def orders(raw_orders):
    ...


@asset_check(asset=orders)
def orders_one_row_per_order(orders):
    duplicated = orders["order_id"].duplicated().sum()
    return AssetCheckResult(passed=bool(duplicated == 0))

When it is fine to leave

An asset whose checks run elsewhere, such as dbt tests on the models a dbt asset builds, is covered. So is a check defined in another file, which this rule cannot see. Tell us which applies, and the finding comes out of your report.

What we need to check it

The Dagster Python files you supply. We read only what they declare (assets, checks, owners), so the finding is medium confidence.