Vertica configurations
Vertica configurations
dbt-vertica 어댑터에서 incremental 모델과 테이블 최적화를 구성하는 방법을 다루는 페이지예요. on_schema_change, incremental_strategy, 그리고 CREATE TABLE의 ORDER BY/SEGMENTED BY/PARTITION BY/KSAFE 절을 설정할 수 있어요.
출처: 문서
본문
Incremental Models 구성
on_schema_change config 파라미터 사용
on_schema_change 파라미터는 ignore, fail, append_new_columns 값을 쓸 수 있어요. sync_all_columns 값은 현재 지원되지 않아요.
ignore (기본값) 파라미터 구성
vertica_incremental.sql
{{config(materialized = 'incremental',on_schema_change='ignore')}}
select * from {{ ref('seed_added') }}
vertica_incremental.sql (컴파일 결과)
insert into "VMart"."public"."merge" ("id", "name", "some_date")
(
select "id", "name", "some_date"
from "merge__dbt_tmp"
)
fail 파라미터 구성
vertica_incremental.sql
{{config(materialized = 'incremental',on_schema_change='fail')}}
select * from {{ ref('seed_added') }}
vertica_incremental.sql (컴파일 결과)
The source and target schemas on this incremental model are out of sync!
They can be reconciled in several ways:
- set the `on_schema_change` config to either append_new_columns or sync_all_columns, depending on your situation.
- Re-run the incremental model with `full_refresh: True` to update the target schema.
- update the schema manually and re-run the process.
Additional troubleshooting context:
Source columns not in target: {{ schema_changes_dict['source_not_in_target'] }}
Target columns not in source: {{ schema_changes_dict['target_not_in_source'] }}
New column types: {{ schema_changes_dict['new_target_types'] }}
append_new_columns 파라미터 구성
vertica_incremental.sql
{{ config( materialized='incremental', on_schema_change='append_new_columns') }}
select * from public.seed_added
vertica_incremental.sql (컴파일 결과)
insert into "VMart"."public"."over" ("id", "name", "some_date", "w", "w1", "t1", "t2", "t3")
(
select "id", "name", "some_date", "w", "w1", "t1", "t2", "t3"
from "over__dbt_tmp"
)
incremental_strategy config 파라미터 사용
append 전략 (기본값):
기존 데이터를 갱신하거나 덮어쓰지 않고 새 레코드만 삽입해요. append는 is_incremental() 조건 블록에 지정된 조건을 기반으로 새 레코드만 추가해요.
vertica_incremental.sql
{{ config( materialized='incremental', incremental_strategy='append' ) }}
select * from public.product_dimension
{% if is_incremental() %}
where product_key > (select max(product_key) from {{this }})
{% endif %}
vertica_incremental.sql (컴파일 결과)
insert into "VMart"."public"."samp" (
"product_key", "product_version", "product_description", "sku_number", "category_description",
"department_description", "package_type_description", "package_size", "fat_content", "diet_type",
"weight", "weight_units_of_measure", "shelf_width", "shelf_height", "shelf_depth", "product_price",
"product_cost", "lowest_competitor_price", "highest_competitor_price", "average_competitor_price", "discontinued_flag")
(
select "product_key", "product_version", "product_description", "sku_number", "category_description", "department_description", "package_type_description", "package_size", "fat_content", "diet_type", "weight", "weight_units_of_measure", "shelf_width", "shelf_height", "shelf_depth", "product_price", "product_cost", "lowest_competitor_price", "highest_competitor_price", "average_competitor_price", "discontinued_flag"
from "samp__dbt_tmp"
)
merge 전략:
unique_key를 기준으로 레코드를 매칭하고, 기존 레코드는 갱신하고 새 것도 삽입해요. (unique_key를 지정하지 않으면 append처럼 모든 새 데이터가 삽입돼요.) merge 전략을 쓰려면 unique_key config 파라미터가 필요한데, 이 파라미터는 단일 테이블 컬럼 값을 받아요.
vertica_incremental.sql
{{ config( materialized = 'incremental', incremental_strategy = 'merge', unique_key='promotion_key' ) }}
select * FROM public.promotion_dimension
vertica_incremental.sql (컴파일 결과)
merge into "VMart"."public"."samp" as DBT_INTERNAL_DEST using "samp__dbt_tmp" as DBT_INTERNAL_SOURCE
on DBT_INTERNAL_DEST."promotion_key" = DBT_INTERNAL_SOURCE."promotion_key"
when matched then update set
"promotion_key" = DBT_INTERNAL_SOURCE."promotion_key", "price_reduction_type" = DBT_INTERNAL_SOURCE."price_reduction_type", "promotion_media_type" = DBT_INTERNAL_SOURCE."promotion_media_type", "display_type" = DBT_INTERNAL_SOURCE."display_type", "coupon_type" = DBT_INTERNAL_SOURCE."coupon_type", "ad_media_name" = DBT_INTERNAL_SOURCE."ad_media_name", "display_provider" = DBT_INTERNAL_SOURCE."display_provider", "promotion_cost" = DBT_INTERNAL_SOURCE."promotion_cost", "promotion_begin_date" = DBT_INTERNAL_SOURCE."promotion_begin_date", "promotion_end_date" = DBT_INTERNAL_SOURCE."promotion_end_date"
when not matched then insert
("promotion_key", "price_reduction_type", "promotion_media_type", "display_type", "coupon_type",
"ad_media_name", "display_provider", "promotion_cost", "promotion_begin_date", "promotion_end_date")
values
(
DBT_INTERNAL_SOURCE."promotion_key", DBT_INTERNAL_SOURCE."price_reduction_type", DBT_INTERNAL_SOURCE."promotion_media_type", DBT_INTERNAL_SOURCE."display_type", DBT_INTERNAL_SOURCE."coupon_type", DBT_INTERNAL_SOURCE."ad_media_name", DBT_INTERNAL_SOURCE."display_provider", DBT_INTERNAL_SOURCE."promotion_cost", DBT_INTERNAL_SOURCE."promotion_begin_date", DBT_INTERNAL_SOURCE."promotion_end_date"
)
merge_update_columns config 파라미터 사용
merge_update_columns config 파라미터는 지정한 컬럼만 갱신하도록 전달되며, 테이블 컬럼 목록을 받아요.
vertica_incremental.sql
{{ config( materialized = 'incremental', incremental_strategy='merge', unique_key = 'id', merge_update_columns = ["names", "salary"] )}}
select * from {{ref('seed_tc1')}}
vertica_incremental.sql (컴파일 결과)
merge into "VMart"."public"."test_merge" as DBT_INTERNAL_DEST using "test_merge__dbt_tmp" as DBT_INTERNAL_SOURCE on DBT_INTERNAL_DEST."id" = DBT_INTERNAL_SOURCE."id"
when matched then update set
"names" = DBT_INTERNAL_SOURCE."names", "salary" = DBT_INTERNAL_SOURCE."salary"
when not matched then insert
("id", "names", "salary")
values
(
DBT_INTERNAL_SOURCE."id", DBT_INTERNAL_SOURCE."names", DBT_INTERNAL_SOURCE."salary"
)
delete+insert 전략:
delete+insert incremental 전략으로 dbt에 두 단계 incremental 접근을 사용하라고 지시할 수 있어요. 먼저 설정된 is_incremental() 블록을 통해 감지된 레코드를 삭제하고, 다시 삽입해요. unique_key는 delete+insert 전략에 필수 파라미터로, 중복 데이터가 있을 때 레코드 갱신 방식을 지정해요. 이 파라미터는 단일 테이블 컬럼 값을 받아요.
vertica_incremental.sql
{{ config( materialized = 'incremental', incremental_strategy = 'delete+insert', unique_key='date_key' ) }}
select * FROM public.date_dimension
vertica_incremental.sql (컴파일 결과)
delete from "VMart"."public"."samp"
where (
date_key) in (
select (date_key)
from "samp__dbt_tmp"
);
insert into "VMart"."public"."samp" (
"date_key", "date", "full_date_description", "day_of_week", "day_number_in_calendar_month", "day_number_in_calendar_year", "day_number_in_fiscal_month", "day_number_in_fiscal_year", "last_day_in_week_indicator", "last_day_in_month_indicator", "calendar_week_number_in_year", "calendar_month_name", "calendar_month_number_in_year", "calendar_year_month", "calendar_quarter", "calendar_year_quarter", "calendar_half_year", "calendar_year", "holiday_indicator", "weekday_indicator", "selling_season")
(
select "date_key", "date", "full_date_description", "day_of_week", "day_number_in_calendar_month", "day_number_in_calendar_year", "day_number_in_fiscal_month", "day_number_in_fiscal_year", "last_day_in_week_indicator", "last_day_in_month_indicator", "calendar_week_number_in_year", "calendar_month_name", "calendar_month_number_in_year", "calendar_year_month", "calendar_quarter", "calendar_year_quarter", "calendar_half_year", "calendar_year", "holiday_indicator", "weekday_indicator", "selling_season"
from "samp__dbt_tmp"
);
insert_overwrite 전략:
insert_overwrite 전략은 레코드를 삭제할 때 전체 테이블 스캔을 사용하지 않아요. 레코드를 삭제하는 대신 전체 파티션을 드롭해요. 이 전략은 partition_by_string과 partitions 파라미터를 받을 수 있어요. 테이블 일부를 덮어쓰고 싶을 때 이 파라미터들을 제공해요.
partition_by_string은 테이블 파티셔닝이 일어나는 기준이 되는 표현식을 받아요. 이것은 Vertica의 PARTITION BY 절이에요.
partitions는 파티션 컬럼의 값 목록을 받아요.
partitions config 파라미터는 신중히 사용해야 해요. 두 가지 상황을 고려하세요.
partitions파라미터의 파티션이 where 절보다 적으면: 대상 테이블에 중복이 생겨요.partitions파라미터의 파티션이 where 절보다 많으면: 대상 테이블에서 행이 누락돼요. 대상이 소스보다 행이 적어져요.
PARTITION BY 절에 대해 더 알아보려면 여기를 확인하세요.
참고: partitions 파라미터는 선택 사항이에요. partitions 파라미터를 제공하지 않으면 where 절의 파티션이 대상에서 드롭되고 소스에서 다시 삽입돼요. where 절을 쓰면 partitions 파라미터가 필요 없을 수 있어요. where 절 조건도 선택 사항이지만, 제공하지 않으면 소스의 모든 데이터가 대상에 삽입돼요. where 절 조건과 partitions 파라미터가 모두 없으면 테이블의 모든 파티션을 드롭하고 전부 다시 삽입해요. partitions 파라미터는 제공했는데 where 절이 없으면, partitions 파라미터의 파티션이 드롭되지만 소스 테이블의 모든 데이터(where 절 없음)가 대상에 삽입되어 대상 테이블에 중복이 생겨요. partition_by_string config 파라미터도 선택 사항이에요. partition_by_string 파라미터를 제공하지 않으면 delete+insert처럼 동작해요. 대상의 모든 레코드를 삭제한 뒤 소스의 모든 레코드를 삽입해요. 파티션을 사용하거나 드롭하지 않아요. partition_by_string과 partitions 파라미터가 모두 없으면 insert_overwrite 전략은 대상 테이블을 truncate하고 소스 테이블 데이터를 대상에 삽입해요. partitions 파라미터를 쓰려면 partition_by_string 파라미터를 전달해 테이블을 파티셔닝해야 해요.
vertica_incremental.sql
{{config(materialized = 'incremental',incremental_strategy = 'insert_overwrite',partition_by_string='YEAR(cc_open_date)',partitions=['2023'])}}
select * from online_sales.call_center_dimension
vertica_incremental.sql (컴파일 결과)
select PARTITION_TABLE('online_sales.update_call_center_dimension');
SELECT DROP_PARTITIONS('online_sales.update_call_center_dimension', '2023', '2023');
SELECT PURGE_PARTITION('online_sales.update_call_center_dimension', '2023');
insert into "VMart"."online_sales"."update_call_center_dimension"
("call_center_key", "cc_closed_date", "cc_open_date", "cc_name", "cc_class", "cc_employees",
"cc_hours", "cc_manager", "cc_address", "cc_city", "cc_state", "cc_region")
(
select "call_center_key", "cc_closed_date", "cc_open_date", "cc_name", "cc_class", "cc_employees",
"cc_hours", "cc_manager", "cc_address", "cc_city", "cc_state", "cc_region"
from "update_call_center_dimension__dbt_tmp"
);
테이블 materialization의 최적화 옵션
모델을 테이블로 materialize할 때 여러 최적화를 쓸 수 있어요. 각 config 파라미터는 생성된 CREATE TABLE DDL에 Vertica 특정 절을 적용해요.
자세한 내용은 Vertica options for table optimization을 참고하세요.
이런 최적화는 아래 예시처럼 모델 SQL 파일에서 구성할 수 있어요.
ORDER BY 절 구성
CREATE TABLE 문의 ORDER BY 절을 활용하려면 모델에서 order_by config 파라미터를 쓰세요.
order_by config 파라미터 사용
vertica_incremental.sql
{{ config( materialized='table', order_by='product_key') }}
select * from public.product_dimension
vertica_incremental.sql (컴파일 결과)
create table "VMart"."public"."order_s__dbt_tmp" as
( select * from public.product_dimension)
order by product_key;
SEGMENTED BY 절 구성
CREATE TABLE 문의 SEGMENTED BY 절을 활용하려면 모델에서 segmented_by_string 또는 segmented_by_all_nodes config 파라미터를 쓰세요. 기본적으로 테이블을 세그먼트하는 데 ALL NODES가 사용되므로, segmented_by_string config 파라미터를 쓰면 SQL 문에 ALL NODES 절이 추가돼요. no_segmentation 파라미터로 ALL NODES를 비활성화할 수 있어요.
segmented by 절에 대해 더 알아보려면 여기를 확인하세요.
segmented_by_string config 파라미터 사용
segmented_by_string config 파라미터는 해시 세그먼테이션 같은 SQL 표현식으로 projection 데이터를 세그먼트하는 데 쓰일 수 있어요.
vertica_incremental.sql
{{ config( materialized='table', segmented_by_string='product_key' ) }}
select * from public.product_dimension
vertica_incremental.sql (컴파일 결과)
create table
"VMart"."public"."segmented_by__dbt_tmp"
as (select * from public.product_dimension)
segmented by product_key ALL NODES;
segmented_by_all_nodes config 파라미터 사용
segmented_by_all_nodes config 파라미터는 모든 클러스터 노드에 분산시키기 위해 projection 데이터를 세그먼트하는 데 쓰일 수 있어요.
참고: segmented_by_all_nodes 파라미터를 전달하려면 segmented_by_string 파라미터를 전달해 테이블을 세그먼트해야 해요.
vertica_incremental.sql
{{ config( materialized='table', segmented_by_string='product_key' ,segmented_by_all_nodes='True' ) }}
select * from public.product_dimension
vertica_incremental.sql (컴파일 결과)
create table "VMart"."public"."segmented_by__dbt_tmp" as
(select * from public.product_dimension)
segmented by product_key ALL NODES;
UNSEGMENTED ALL NODES 절 구성
CREATE TABLE 문의 UNSEGMENTED ALL NODES 절을 활용하려면 모델에서 no_segmentation config 파라미터를 쓰세요.
no_segmentation config 파라미터 사용
vertica_incremental.sql
{{config(materialized='table',no_segmentation='true')}}
select * from public.product_dimension
vertica_incremental.sql (컴파일 결과)
create table
"VMart"."public"."ww__dbt_tmp"
INCLUDE SCHEMA PRIVILEGES as (
select * from public.product_dimension )
UNSEGMENTED ALL NODES ;
PARTITION BY 절 구성
CREATE TABLE 문의 PARTITION BY 절을 활용하려면 모델에서 partition_by_string, partition_by_active_count, partition_by_group_by_string config 파라미터를 쓰세요.
partition by 절에 대해 더 알아보려면 여기를 확인하세요.
partition_by_string config 파라미터 사용
partition_by_string (선택)은 테이블 데이터 파티셔닝이 일어나는 기준이 되는 특정 column_name 하나의 문자열 값을 받아요.
vertica_incremental.sql
{{ config( materialized='table', partition_by_string='employee_age' )}}
select * FROM public.employee_dimension
vertica_incremental.sql (컴파일 결과)
create table "VMart"."public"."test_partition__dbt_tmp" as
( select * FROM public.employee_dimension);
alter table "VMart"."public"."test_partition__dbt_tmp"
partition BY employee_age
partition_by_active_count config 파라미터 사용
partition_by_active_count (선택)은 이 테이블에 몇 개의 파티션이 활성인지 지정해요. 정수 값을 받아요.
참고: partition_by_active_count 파라미터를 전달하려면 partition_by_string 파라미터를 전달해 테이블을 파티셔닝해야 해요.
vertica_incremental.sql
{{ config( materialized='table',
partition_by_string='employee_age',
partition_by_group_by_string="""
CASE WHEN employee_age < 5 THEN 1
WHEN employee_age>50 THEN 2
ELSE 3 END""",
partition_by_active_count = 2) }}
select * FROM public.employee_dimension
vertica_incremental.sql (컴파일 결과)
create table "VMart"."public"."test_partition__dbt_tmp" as
( select * FROM public.employee_dimension );
alter table "VMart"."public"."test_partition__dbt_tmp" partition BY employee_ag
group by CASE WHEN employee_age < 5 THEN 1
WHEN employee_age>50 THEN 2
ELSE 3 END
SET ACTIVEPARTITIONCOUNT 2 ;
partition_by_group_by_string config 파라미터 사용
partition_by_group_by_string 파라미터(선택)은 각 그룹 케이스를 단일 문자열로 지정하는 문자열을 받아요.
이것은 partition_by_string 값에서 파생돼요.
partition_by_group_by_string 파라미터는 파티션을 별도의 파티션 그룹으로 병합하는 데 쓰여요.
참고: partition_by_group_by_string 파라미터를 전달하려면 partition_by_string 파라미터를 전달해 테이블을 파티셔닝해야 해요.
vertica_incremental.sql
{{config(materialized='table',
partition_by_string='number_of_children',
partition_by_group_by_string="""
CASE WHEN number_of_children <= 2 THEN 'small_family'
ELSE 'big_family' END""")}}
select * from public.customer_dimension
vertica_incremental.sql (컴파일 결과)
create table "VMart"."public"."test_partition__dbt_tmp" INCLUDE SCHEMA PRIVILEGES as
( select * from public.customer_dimension ) ;
alter table "VMart"."public"."test_partition__dbt_tmp"
partition BY number_of_children
group by CASE WHEN number_of_children <= 2 THEN 'small_family'
ELSE 'big_family' END ;
KSAFE 절 구성
CREATE TABLE 문의 KSAFE 절을 활용하려면 모델에서 ksafe config 파라미터를 쓰세요.
vertica_incremental.sql
{{ config( materialized='table', ksafe='1' ) }}
select * from public.product_dimension
vertica_incremental.sql (컴파일 결과)
create table "VMart"."public"."segmented_by__dbt_tmp" as
(select * from public.product_dimension )
ksafe 1;
더 알아보기 (Learn more)
- Vertica 설정 — 어댑터 연결.
- Incremental models — incremental 전략과 on_schema_change.