Help with Call Statement Error - 'None' has no attribute 'table'

I’m getting an error (‘None’ has no attribute ‘table’) for the following:

{% macro check_if_column_exists_in_table(schemaName, tableName, columnName) %}

{%- call statement(‘result’, fetch_result=True) -%}

select exists (
SELECT 1
FROM information_schema.columns
WHERE table_schema=
‘{{ schemaName }}’
AND table_name=’{{ tableName }}’ AND column_name=’{{ columnName }}’) as “result”

{%- endcall -%}

{%- set result = load_result(‘result’).table.columns[‘result’].values()[0] -%}

{{return(result)}}

{% endmacro %}

Hey @chanwd - dbt needs to run the jinja code in models and macros twice:

  1. first pass: extract refs/configs so dbt knows how to build the project
  2. second pass: actually execute the sql against the database

During the first pass (what we call “parsing”), dbt intentionally doesn’t run statement blocks. We do this intentionally to make parsing faster. While this is a very good speed improvement, it also means that on the first pass through your project, dbt returns none from load_result() instead of the actual query results.

To work around this, you can use the execute context variable to determine if dbt is in “parsing” mode (first pass) or “execute” mode (second pass). In practice, that works like:

{% macro check_if_column_exists_in_table(schemaName, tableName, columnName) %}

{%- call statement(‘result’, fetch_result=True) -%}

select exists (
SELECT 1
FROM information_schema.columns
WHERE table_schema=
‘{{ schemaName }}’
AND table_name=’{{ tableName }}’ AND column_name=’{{ columnName }}’) as “result”

{%- endcall -%}

{% if execute %}
  {%- set result = load_result(‘result’).table.columns[‘result’].values()[0] -%}
  {{return(result)}}
{% else %}
  {{ return(false) }}
{% endif %}

{% endmacro %}

In the if/else block at the bottom of the macro, you can return a phony value at parse-time to help the macro code compile. At runtime, execute will be true, and this macro will return the “real” value for the statement query!

This could definitely be better documented - stay tuned for relevant updates to the docs!

Thanks Drew, I just figured it out on my own that my code to access the value needed to be within the if execute block but I couldn’t understand why.

Thank you for the clarification!