What's the issue?
When DagsterDbtTranslatorSettings(enable_source_tests_as_checks=True) is set, single-dependency source tests (not_null, unique) are correctly modeled as Dagster asset checks. However, relationships tests defined on a source column are silently dropped — no asset check is ever created for them.
The tests still execute as part of dbt build, so data-quality enforcement is intact, but they are invisible in Dagster: no asset-check tile, no lineage, and a failure surfaces only as the parent asset failing rather than as a named check.
This is specific to source tests with more than one dependency. The equivalent relationships test defined on a model column works correctly.
What did you expect to happen?
The source relationships test is modeled as an asset check attached to the "from" source asset (foo), consistent with how a relationships test on a model column is attached to its model.
How to reproduce?
sources.yml:
version: 2
sources:
- name: my_source
schema: my_schema
tables:
- name: foo
columns:
- name: id
data_tests: [not_null, unique] # -> becomes an asset check ✅
- name: bar_id
data_tests:
- relationships: # -> NO asset check created ❌
arguments:
to: source('my_source', 'bar')
field: id
- name: bar
columns:
- name: id
data_tests: [not_null, unique]
dbt registers the test correctly (dbt ls --resource-type test --select source:my_source.foo lists source_relationships_my_source_foo_id__id__source_my_source_bar_), but it does not appear as an asset check in Dagster.
There is no relationship asset check in dagster:
Dagster version
1.12.14
Deployment type
Dagster Cloud
Deployment details
No response
Additional information
I understand the issue is not necessary and can go straight to the PR, but wanted to capture the problem we were seeing. I will open a PR with the fix!
Root cause
In dagster_dbt/asset_utils.py, the function that maps a test to an AssetCheckKey determines the attached asset as follows:
# asset_utils.py (~L982-L1026)
upstream_unique_ids = set(test_resource_props["depends_on"]["nodes"])
attached_node_unique_id = test_resource_props.get("attached_node")
# If the test is singular, infer the attached node from the upstream nodes.
if len(upstream_unique_ids) == 1:
[attached_node_unique_id] = upstream_unique_ids
# ... meta.dagster.ref fallback (searches manifest["nodes"] only) ...
if not attached_node_unique_id:
return None
dbt populates attached_node for generic tests defined on models/seeds/snapshots, but leaves it None for tests defined on sources. For source tests this is normally rescued by the len(upstream_unique_ids) == 1 fallback — but a relationships test has two dependencies (the "from" table and the "to" table), so that branch never fires, attached_node_unique_id stays None, and the function returns None.
The config.meta.dagster.ref escape hatch does not help here either: its lookup loop iterates manifest["nodes"] only and never scans manifest["sources"], so a ref pointing at a source asset cannot resolve. (Arguably a second, related bug.)
Suggested fix
When attached_node is None and the test has multiple dependencies, fall back to the test's own anchor instead of giving up. The manifest carries enough to disambiguate a relationships test:
column_name (e.g. bar_id) and the test name / file_key_name identify the "from" source.
- The
to: argument identifies the other dependency.
Attaching the check to the "from" source would make source relationships tests behave like their model counterparts. Additionally, extending the meta.dagster.ref lookup to also search manifest["sources"] would give users an explicit override for the multi-dependency source case.
Message from the maintainers
Impacted by this issue? Give it a 👍! We factor engagement into prioritization.
What's the issue?
When
DagsterDbtTranslatorSettings(enable_source_tests_as_checks=True)is set, single-dependency source tests (not_null,unique) are correctly modeled as Dagster asset checks. However,relationshipstests defined on a source column are silently dropped — no asset check is ever created for them.The tests still execute as part of
dbt build, so data-quality enforcement is intact, but they are invisible in Dagster: no asset-check tile, no lineage, and a failure surfaces only as the parent asset failing rather than as a named check.This is specific to source tests with more than one dependency. The equivalent
relationshipstest defined on a model column works correctly.What did you expect to happen?
The source
relationshipstest is modeled as an asset check attached to the "from" source asset (foo), consistent with how arelationshipstest on a model column is attached to its model.How to reproduce?
sources.yml:dbt registers the test correctly (
dbt ls --resource-type test --select source:my_source.foolistssource_relationships_my_source_foo_id__id__source_my_source_bar_), but it does not appear as an asset check in Dagster.There is no relationship asset check in dagster:
Dagster version
1.12.14
Deployment type
Dagster Cloud
Deployment details
No response
Additional information
I understand the issue is not necessary and can go straight to the PR, but wanted to capture the problem we were seeing. I will open a PR with the fix!
Root cause
In
dagster_dbt/asset_utils.py, the function that maps a test to anAssetCheckKeydetermines the attached asset as follows:dbt populates
attached_nodefor generic tests defined on models/seeds/snapshots, but leaves itNonefor tests defined on sources. For source tests this is normally rescued by thelen(upstream_unique_ids) == 1fallback — but arelationshipstest has two dependencies (the "from" table and the "to" table), so that branch never fires,attached_node_unique_idstaysNone, and the function returnsNone.The
config.meta.dagster.refescape hatch does not help here either: its lookup loop iteratesmanifest["nodes"]only and never scansmanifest["sources"], so arefpointing at a source asset cannot resolve. (Arguably a second, related bug.)Suggested fix
When
attached_nodeisNoneand the test has multiple dependencies, fall back to the test's own anchor instead of giving up. The manifest carries enough to disambiguate arelationshipstest:column_name(e.g.bar_id) and the test name /file_key_nameidentify the "from" source.to:argument identifies the other dependency.Attaching the check to the "from" source would make source
relationshipstests behave like their model counterparts. Additionally, extending themeta.dagster.reflookup to also searchmanifest["sources"]would give users an explicit override for the multi-dependency source case.Message from the maintainers
Impacted by this issue? Give it a 👍! We factor engagement into prioritization.