Мне нужна помощь в создании моей первой инкрементальной модели.
В таблице Campampchannel Channel у меня есть столбец surrogate_key, который принимает clientcode_id и объединяет номер индекса для его создания, который действует как уникальный ключ. Идея состоит в том, что при создании новой кампании мы найдем максимальный surrogate_id для этого клиента и +1, чтобы у нас был способ иметь уникальный идентификатор для всех кампаний по клиенту. Будет ли дополнительная работа в этом случае?
Кроме того, полезно ли иметь резервную копию для дополнительных моделей?
Это SQL-код Python
-- dbt campaign channel level dimension : dim_campaignchannel
{{ config(materialized='incremental', unique_key=surrogate_key) }}
SELECT --ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername) AS index_number,
CAST(CONCAT(c.clientcode_id, ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername)) as numeric) AS surrogate_key, c.* from
(
SELECT b.clientcode_id, a.clientcode, a.adservername, a.mediachannel, a.adtech, a.programname, a.funnelstage, a.period, a.season, a.campaigntype
,a.lob, a.businessline, a.objective, a.market, a.targettype, a.subcampaign, a.campaignyear, a.startdate, a.enddate
FROM public.map_campaign_segments a
JOIN
public.map_client_segments b ON a.clientcode = b.clientcode
where a.adservername != '-'
order by a.clientcode, a.adservername) c
order by c.clientcode, c.adservername
Вот что я придумал, не уверен, что это правильный подход:
-- dbt campaign channel level dimension : dim_campaignchannel_master
{{ config(materialized='incremental',
unique_key='surrogate_key') }}
SELECT
CASE
WHEN EXISTS (
SELECT 1 FROM dim_campaignchannel WHERE adservername = c.adservername
) THEN
CAST(CONCAT(c.clientcode_id, ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername)) as numeric) -- Generate a new surrogate key if adservername exists
ELSE
(SELECT MAX(surrogate_key) + 1 FROM dim_campaignchannel WHERE clientcode = c.clientcode) -- Increment the surrogate key for existing clientcode
END AS surrogate_key,
c.*
FROM (
SELECT
b.clientcode_id, a.clientcode, a.adservername, a.mediachannel, a.adtech, a.programname, a.funnelstage, a.period, a.season, a.campaigntype,
a.lob, a.businessline, a.objective, a.market, a.targettype, a.subcampaign, a.campaignyear, a.startdate, a.enddate
FROM
public.map_campaign_segments a
JOIN
public.map_client_segments b ON a.clientcode = b.clientcode
WHERE
a.adservername != '-'
ORDER BY
a.clientcode, a.adservername
) c
{% if is_incremental() %}
-- this filter will only be applied on an incremental run
-- (uses >= to include records arriving later on the same day as the last run of this model)
WHERE
NOT EXISTS (
SELECT 1 FROM dim_campaignchannel WHERE adservername = c.adservername
)
{% endif %}
ORDER BY
c.clientcode, c.adservername
Вероятно, существует неправильное представление о том, для чего нужна поэтапная материализация.
Инкрементальные модели:
✅ служат для оптимизации рабочей нагрузки dbt (если dbt run
выполняется слишком долго)
❌ не служат для постепенной генерации уникальных ключей
Высока вероятность, что на данном этапе вам не понадобится инкрементальная модель.
Руководство по передовому опыту dbt говорит:
Начните как можно проще
Так что сейчас самое время задуматься о переходе на инкрементный режим, когда выполнение dbt становится слишком долгим и тяжелым. При этом к генерации суррогатных/первичных/инкрементных ключей это не имеет никакого отношения.
Несколько примечаний:
ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername))
может быть подвержено ошибкам. Потому что в разное время суррогатный_ключ может иметь разные значения для одной и той же клиентской кампании. Если возможно, добавьте временную метку ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername, c.campaign_created_timestamp))