You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Many dbt_utils macros need to access information about an underlying table, by running adapter.get_columns_in_relation or a custom query.
Those macros expect to be passed a ref, source, or other Relation object, and for it to represent an object that really exists in the database. To ensure that's the case, and raise a helpful error if it isn't, they first call "internal helper" macros, _is_relation and _is_ephemeral, to check that the passed argument (a) really is a Relation, (b) isn't ephemeral (= exists as a database object, assuming it's already been run).
Because this is Jinja, we can't just call isinstance, or classmethods. We have to check meta properties.
{% macro _is_relation(obj, macro) %}
{%- if not (obj is mapping and obj.get('metadata', {}).get('type', '').endswith('Relation')) -%}
{%- do exceptions.raise_compiler_error("Macro " ~ macro ~ " expected a Relation but received the value: " ~ obj) -%}
{%- endif -%}
{% endmacro %}
There is a node method, is_ephemeral, but nothing available on the actual Relation object returned by ref... except the is_cte property:
{% macro _is_ephemeral(obj, macro) %}
{%- if obj.is_cte -%}
{% set ephemeral_prefix = api.Relation.add_ephemeral_prefix('') %}
{% if obj.name.startswith(ephemeral_prefix) %}
{% set model_name = obj.name[(ephemeral_prefix|length):] %}
{% else %}
{% set model_name = obj.name %}
{%- endif -%}
{% set error_message %}
The `{{ macro }}` macro cannot be used with ephemeral models, as it relies on the information schema.
`{{ model_name }}` is an ephemeral model. Consider making it a view or table instead.
{% endset %}
{%- do exceptions.raise_compiler_error(error_message) -%}
{%- endif -%}
{% endmacro %}
Questions
Is there a better way to write these? Are there better properties / classmethods we could expose on the Relation object, to make it accessible in the Jinja layer?
Should these checks actually be happening within adapter methods like adapter.get_columns_in_relation?
The text was updated successfully, but these errors were encountered:
Chiming in here - I would find isinstance/type useful for a use case I have. I'm processing data in macro that comes from the config/meta dictionaries and being able to understand the the data type of the value in the dictionary would be useful.
Many
dbt_utils
macros need to access information about an underlying table, by runningadapter.get_columns_in_relation
or a custom query.Those macros expect to be passed a
ref
,source
, or otherRelation
object, and for it to represent an object that really exists in the database. To ensure that's the case, and raise a helpful error if it isn't, they first call "internal helper" macros,_is_relation
and_is_ephemeral
, to check that the passed argument (a) really is a Relation, (b) isn't ephemeral (= exists as a database object, assuming it's already been run).Because this is Jinja, we can't just call
isinstance
, or classmethods. We have to check meta properties.dbt_utils._is_relation
dbt_utils._is_ephemeral
There is a node method, is_ephemeral, but nothing available on the actual
Relation
object returned byref
... except theis_cte
property:Questions
Relation
object, to make it accessible in the Jinja layer?adapter.get_columns_in_relation
?The text was updated successfully, but these errors were encountered: