Reputation: 65
Trying to call a stored procedure using a Model. Call is made using a custom macro as below,
{% materialization call_proc, adapter='snowflake' -%}
{%- call statement('main') -%}
{{ sql }}
{%- endcall -%}
{%- endmaterialization %}
Model definition:
{{ config(
materialized='call_proc',
database='TEST_DB',
schema = 'TEST',
pre_hook = "use schema {{ database }}.{{ schema }};"
)
}}
call "{{ database }}"."{{ schema }}".TEST_PROC('SAMPLE');
Procedure is a Snowflake Procedure created with "Execute as Caller" property. In snowflake history i can see this is called with db/schema. Internally the procedure calls another procedure which doesn't use fully qualified name. Ideally since it a Execute as Caller, the internal procedure should run using the DB/SCHEMA context set. FOr that i have specifically put in USE DB.SCHEMA as pre hook but seems it is not working.
Any ideas? I dont want to use fully qualified names in the call statement inside procedure body or even pass as parameter.
Upvotes: 1
Views: 2384
Reputation: 5815
dbt uses a different session to execute pre-hooks and model code; use ...
only applies to the current session, which is why the pre-hook has no effect on the behavior of your stored procedure.
Generally, calling stored procedures like this from dbt is a hack: dbt runs should be idempotent, so if you are inserting or deleting data, etc., then you're breaking the dbt paradigm, which is why stored procedures aren't supported more directly.
That said, if you have to use one, I would wrap it in a macro and then call that macro in either an on-run-start
hook, a pre-hook
, or using dbt's run-operation
command. Models are intended to map 1:1 with database relations, and hacking a materialization macro like you have is really not ideal.
You can also use the target
context variable to retrieve database
and schema
from your profile:
-- in macros/call_test_proc.sql
{% macro call_test_proc(my_arg) %}
begin;
use database {{ target.database }};
use schema {{ target.schema }};
call TEST_PROC('{{ my_arg }}');
commit;
{% endmacro %}
Then from the command line:
dbt run-operation call_test_proc --args '{"my_arg": "SAMPLE"}' --target dev
Or as a hook:
# in dbt_project.yml
on-run-start: "{{ call_test_proc('SAMPLE') }}"
Upvotes: 0