graph 컨텍스트 변수
graph 컨텍스트 변수
graph 컨텍스트 변수에는 dbt 프로젝트의 노드(node) 에 대한 정보가 들어 있어요. dbt 프로젝트에서 모델, 소스, 테스트, 스냅샷이 모두 노드의 예시랍니다. 이 변수는 파싱된 프로젝트 매니페스트를 바탕으로 노드들의 구조를 미리 파악할 때 유용해요.
출처: 문서
본문
graph 컨텍스트 변수
graph 컨텍스트 변수는 노드 id를 그 노드의 사전 표현(dictionary representation)으로 매핑하는 사전(dictionary)이에요. 간단한 예시는 다음과 같아요:
{
"nodes": {
"model.my_project.model_name": {
"unique_id": "model.my_project.model_name",
"config": {"materialized": "table", "sort": "id"},
"tags": ["abc", "123"],
"path": "models/path/to/model_name.sql",
...
},
...
},
"sources": {
"source.my_project.snowplow.event": {
"unique_id": "source.my_project.snowplow.event",
"database": "analytics",
"schema": "analytics",
"tags": ["abc", "123"],
"path": "models/path/to/schema.yml",
...
},
...
},
"exposures": {
"exposure.my_project.traffic_dashboard": {
"unique_id": "exposure.my_project.traffic_dashboard",
"type": "dashboard",
"maturity": "high",
"path": "models/path/to/schema.yml",
...
},
...
},
"metrics": {
"metric.my_project.count_all_events": {
"unique_id": "metric.my_project.count_all_events",
"type": "count",
"path": "models/path/to/schema.yml",
...
},
...
},
"groups": {
"group.my_project.finance": {
"unique_id": "group.my_project.finance",
"name": "finance",
"owner": {
"email": "[email protected]"
}
...
},
...
}
}
모델·소스 노드에 대한 정확한 계약(contract)은 아직 문서화되지 않았지만, 앞으로 문서화될 예정이에요.
주의해요 — 파싱 단계에서
graph변수가 만들어지기 때문에, dbt 프로젝트 실행 중 parsing phase 동안에는graph컨텍스트 변수의 일부 속성이 누락되거나 부정확할 수 있어요. 아래 내용을 꼼꼼히 읽고 이 변수를 효과적으로 사용하는 방법을 이해하세요.
모델에 접근하기
graph 사전의 model 항목은 파싱 중에는 불완전하거나 부정확할 수 있어요. graph 변수로 프로젝트의 모델에 접근한다면, 반드시 execute 플래그를 사용해 이 코드가 파싱 시점이 아니라 런타임에만 실행되도록 하세요. DAG를 만들 때 graph 변수를 쓰지 마세요. 그렇게 하면 dbt 동작이 정의되지 않고 아마도 부정확해질 거예요. 사용 예시:
graph-usage.sql
/*
Print information about all of the models in the Snowplow package
*/
{% if execute %}
{% for node in graph.nodes.values()
| selectattr("resource_type", "equalto", "model")
| selectattr("package_name", "equalto", "snowplow") %}
{% do log(node.unique_id ~ ", materialized: " ~ node.config.materialized, info=true) %}
{% endfor %}
{% endif %}
/*
Example output
---------------------------------------------------------------
model.snowplow.snowplow_id_map, materialized: incremental
model.snowplow.snowplow_page_views, materialized: incremental
model.snowplow.snowplow_web_events, materialized: incremental
model.snowplow.snowplow_web_page_context, materialized: table
model.snowplow.snowplow_web_events_scroll_depth, materialized: incremental
model.snowplow.snowplow_web_events_time, materialized: incremental
model.snowplow.snowplow_web_events_internal_fixed, materialized: ephemeral
model.snowplow.snowplow_base_web_page_context, materialized: ephemeral
model.snowplow.snowplow_base_events, materialized: ephemeral
model.snowplow.snowplow_sessions_tmp, materialized: incremental
model.snowplow.snowplow_sessions, materialized: table
*/
소스에 접근하기
dbt 프로젝트의 소스에 프로그래밍 방식으로 접근하려면 graph 객체의 sources 속성을 사용하세요.
사용 예시:
models/events_unioned.sql
/*
Union all of the Snowplow sources defined in the project
which begin with the string "event_"
*/
{% set sources = [] -%}
{% for node in graph.sources.values() -%}
{%- if node.name.startswith('event_') and node.source_name == 'snowplow' -%}
{%- do sources.append(source(node.source_name, node.name)) -%}
{%- endif -%}
{%- endfor %}
select * from (
{%- for source in sources %}
select * from {{ source }} {% if not loop.last %} union all {% endif %}
{% endfor %}
)
/*
Example compiled SQL
---------------------------------------------------------------
select * from (
select * from raw.snowplow.event_add_to_cart union all
select * from raw.snowplow.event_remove_from_cart union all
select * from raw.snowplow.event_checkout
)
*/
exposure에 접근하기
dbt 프로젝트의 exposure에 프로그래밍 방식으로 접근하려면 graph 객체의 exposures 속성을 사용하세요.
사용 예시:
models/my_important_view_model.sql
{# Include a SQL comment naming all of the exposures that this model feeds into #}
{% set exposures = [] -%}
{% for exposure in graph.exposures.values() -%}
{%- if model['unique_id'] in exposure.depends_on.nodes -%}
{%- do exposures.append(exposure) -%}
{%- endif -%}
{%- endfor %}
-- HELLO database administrator! Before dropping this view,
-- please be aware that doing so will affect:
{% for exposure in exposures %}
-- * {{ exposure.name }} ({{ exposure.type }})
{% endfor %}
/*
Example compiled SQL
---------------------------------------------------------------
-- HELLO database administrator! Before dropping this view,
-- please be aware that doing so will affect:
-- * our_metrics (dashboard)
-- * my_sync (application)
*/
metric에 접근하기
dbt 프로젝트의 metric에 프로그래밍 방식으로 접근하려면 graph 객체의 metrics 속성을 사용하세요.
사용 예시:
macros/get_metric.sql
{% macro get_metric_sql_for(metric_name) %}
{% set metrics = graph.metrics.values() %}
{% set metric = (metrics | selectattr('name', 'equalto', metric_name) | list).pop() %}
/* Elsewhere, I've defined a macro, get_metric_timeseries_sql, that will return
the SQL needed to perform a time-based rollup of this metric's calculation */
{% set metric_sql = get_metric_timeseries_sql(
relation = metric['model'],
type = metric['type'],
expression = metric['sql'],
...
) %}
{{ return(metric_sql) }}
{% endmacro %}
group에 접근하기
dbt 프로젝트의 group에 프로그래밍 방식으로 접근하려면 graph 객체의 groups 속성을 사용하세요.
사용 예시:
macros/get_group.sql
{% macro get_group_owner_for(group_name) %}
{% set groups = graph.groups.values() %}
{% set owner = (groups | selectattr('owner', 'equalto', group_name) | list).pop() %}
{{ return(owner) }}
{% endmacro %}
더 알아보기 (Learn more)
graph변수는 주로execute플래그와 함께 써서 런타임에만 안전하게 접근해요.- 관련 개념: execute 컨텍스트 변수, 모델·소스·exposure·metric 정의 문서.