From cb00d62224c59c62c463615121cbd3e6b53c146b Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 14:37:16 +0000 Subject: [PATCH 1/2] fix: handle dbt deferral in get_elementary_relation When --favor-state or --defer is active, Elementary models may not be built in the CI target schema. adapter.get_relation() returns None in this case, causing anomaly tests to fail with 'relation "none" does not exist'. Fall back to constructing a Relation from graph node coordinates when the physical catalog lookup returns None but the node exists in the dbt graph. This allows the generated SQL to reference the correct (deferred) schema. Co-Authored-By: Noy Arie --- .../utils/graph/get_elementary_relation.sql | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/macros/utils/graph/get_elementary_relation.sql b/macros/utils/graph/get_elementary_relation.sql index a50de55e0..11f2f488a 100644 --- a/macros/utils/graph/get_elementary_relation.sql +++ b/macros/utils/graph/get_elementary_relation.sql @@ -20,10 +20,24 @@ {% if this and this.database == elementary_database and this.schema == elementary_schema and this.identifier == identifier_alias %} {% do return(this) %} {% endif %} - {% do return( - adapter.get_relation( - elementary_database, elementary_schema, identifier_alias - ) + {% set relation = adapter.get_relation( + elementary_database, elementary_schema, identifier_alias ) %} + {% if relation is not none %} {% do return(relation) %} {% endif %} + {# Relation not found in the target schema. This can happen when + dbt deferral (--favor-state / --defer) is active and the + Elementary models exist in the deferred (e.g. prod) schema + but were not built in the current target. Construct a relation + from the graph node coordinates so the generated SQL references + the correct schema instead of rendering "from None". #} + {% if identifier_node %} + {% do return( + api.Relation.create( + database=elementary_database, + schema=elementary_schema, + identifier=identifier_alias, + ) + ) %} + {% endif %} {%- endif %} {% endmacro %} From fdcb302a93a57bd1f2b2ac49dbdea7500967a675 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 14:49:44 +0000 Subject: [PATCH 2/2] fix: gate deferral fallback on --defer/--favor-state flags Only construct a synthetic Relation when dbt deferral is actually active (invocation_args_dict.defer or favor_state). Without this guard, the fallback would fire for any installed Elementary model whose table doesn't exist yet (e.g. partial dbt run), breaking callers that rely on a None return to detect missing tables. Co-Authored-By: Noy Arie --- .../utils/graph/get_elementary_relation.sql | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/macros/utils/graph/get_elementary_relation.sql b/macros/utils/graph/get_elementary_relation.sql index 11f2f488a..76b99d65d 100644 --- a/macros/utils/graph/get_elementary_relation.sql +++ b/macros/utils/graph/get_elementary_relation.sql @@ -24,13 +24,21 @@ elementary_database, elementary_schema, identifier_alias ) %} {% if relation is not none %} {% do return(relation) %} {% endif %} - {# Relation not found in the target schema. This can happen when - dbt deferral (--favor-state / --defer) is active and the - Elementary models exist in the deferred (e.g. prod) schema - but were not built in the current target. Construct a relation - from the graph node coordinates so the generated SQL references - the correct schema instead of rendering "from None". #} - {% if identifier_node %} + {# Relation not found in the target schema. Under dbt deferral + (--favor-state / --defer) the Elementary models may exist only + in the deferred (e.g. prod) schema and not in the current + target. Construct a relation from the graph node coordinates + so the generated SQL references the correct schema instead of + rendering "from None". #} + {% set is_defer = ( + ( + invocation_args_dict.get("defer", false) + or invocation_args_dict.get("favor_state", false) + ) + if invocation_args_dict + else false + ) %} + {% if identifier_node and is_defer %} {% do return( api.Relation.create( database=elementary_database,