Skip to content

Add artifact creation and asset tracking to per-node dbt orchestrator#20743

Merged
desertaxle merged 13 commits intomainfrom
feat/per-node-dbt-orchestration-phase-9
Feb 18, 2026
Merged

Add artifact creation and asset tracking to per-node dbt orchestrator#20743
desertaxle merged 13 commits intomainfrom
feat/per-node-dbt-orchestration-phase-9

Conversation

@desertaxle
Copy link
Member

@desertaxle desertaxle commented Feb 18, 2026

This PR adds Prefect artifact creation and asset lineage tracking to the per-node dbt orchestrator, along with configurable test execution strategies and several correctness fixes.

Changes

Artifact support (_artifacts.py)

  • create_summary_markdown: builds a markdown summary of run_build() results, posted as a Prefect artifact at the end of each build
  • create_run_results_dict / write_run_results_json: emits a dbt-compatible run_results.json (schema v6) for downstream tooling integration
  • create_asset_for_node / get_upstream_assets_for_node: creates Prefect Asset objects with lineage tracking for models, seeds, and snapshots
  • get_compiled_code_for_node: optionally attaches compiled SQL to asset descriptions

New orchestrator options

  • create_summary_artifact (default True): posts a markdown build summary to the Prefect UI
  • write_run_results (default False): writes run_results.json to the target directory
  • include_compiled_code (default False): includes compiled SQL in asset descriptions

Asset lineage

  • Nodes with a relation_name are wrapped in MaterializingTask, tracking the materialized database object as a Prefect asset
  • Upstream assets are resolved through ephemeral models so lineage reaches actual source tables
  • Asset metadata (status, execution time) is attached via AssetContext on success

Test execution strategies (TestStrategy enum)

  • SKIP (default): tests excluded entirely
  • IMMEDIATE: tests interleaved with models via Kahn's algorithm — each test runs in the wave after all its parent models complete
  • DEFERRED: all model waves execute first, then a final test wave

Bug fixes

  • Removed unguarded NodeType.Unit reference that caused AttributeError on dbt-core 1.7.x
  • Fixed cache disabled for nodes whose upstream dependencies were excluded by selectors, preventing stale cache reuse on partial selections
  • Fixed test failure cascade in PER_WAVE mode — test failures no longer cause downstream model waves to be skipped
  • Fixed target_path resolution when an explicit manifest_path is provided
  • relation_name included in cache key so relation renames correctly invalidate the cache

@desertaxle desertaxle marked this pull request as ready for review February 18, 2026 17:54
@desertaxle desertaxle changed the title Add test strategies, artifacts, and cache improvements to per-node dbt orchestrator Add artifact creation and asset tracking to per-node dbt orchestrator Feb 18, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 38574147fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Collaborator

@zzstoatzz zzstoatzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! a couple non-blocking observations

Base automatically changed from feat/per-node-dbt-orchestration-phase-8 to main February 18, 2026 19:29
desertaxle and others added 12 commits February 18, 2026 13:34
Introduces TestStrategy enum (IMMEDIATE, DEFERRED, SKIP) that controls
when dbt test and unit_test nodes execute during orchestrated builds.
SKIP is the default for backward compatibility.

- Add get_test_nodes() and filter_test_nodes() to ManifestParser
- Support both NodeType.Test and NodeType.Unit in test collection
- Suppress dbt indirect test selection (indirect_selection='empty') in
  PER_WAVE mode with narrowed TypeError fallback for legacy executors
- Exclude test nodes from caching in PER_NODE mode
- Add schema.yml fixtures for integration test determinism
- Add 48 unit tests and 8 integration tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…me accuracy

Adds summary markdown artifacts, run_results.json output, compiled code
inclusion, and asset lineage tracking to the per-node dbt orchestrator.
Fixes create_markdown_artifact to use _sync=True so it works correctly
in async flow contexts, and prefers dbt-reported execution_time over
orchestrator-measured duration_seconds in run_results output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…in PER_WAVE

Disable caching for nodes whose upstream dependencies were not executed
in the current run (e.g. excluded by select=...), preventing stale
downstream results from being reused when an upstream changes separately.

In PER_WAVE IMMEDIATE mode, use per-node artifact status to distinguish
individually successful models from failed tests in the same wave, so
test failures no longer incorrectly propagate as model failures to
downstream waves.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add relation_name to DbtNodeCachePolicy key material so that runs
targeting different dbt environments (e.g. dev vs prod schemas) produce
distinct cache keys and cannot incorrectly skip execution.

Always pass --target-path to dbt source freshness using the resolved
output target so that a custom settings.target_path is honoured and
sources.json is written to the expected location.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…it ref

The duplicate _TEST_NODE_TYPES assignment unconditionally accessed
NodeType.Unit, breaking module import on dbt-core 1.7.x. Remove the
duplicate; the guarded frozenset using _UNIT_TYPE is sufficient.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…strator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ator

Patching a name must target the module that has already imported it.
After moving create_markdown_artifact, create_asset_for_node,
get_upstream_assets_for_node, and get_compiled_code_for_node from
deferred imports to top-level imports in _orchestrator, the patch
targets need to reference prefect_dbt.core._orchestrator.* rather
than their source modules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@desertaxle desertaxle force-pushed the feat/per-node-dbt-orchestration-phase-9 branch from f1ba55f to 50a441e Compare February 18, 2026 19:34
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@desertaxle desertaxle merged commit ebea936 into main Feb 18, 2026
21 checks passed
@desertaxle desertaxle deleted the feat/per-node-dbt-orchestration-phase-9 branch February 18, 2026 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants