Использование Materialized='Incremental' для добавления новых кампаний в таблицу

Мне нужна помощь в создании моей первой инкрементальной модели.

В таблице 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
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вероятно, существует неправильное представление о том, для чего нужна поэтапная материализация.

Инкрементальные модели:
✅ служат для оптимизации рабочей нагрузки dbt (если dbt run выполняется слишком долго)
❌ не служат для постепенной генерации уникальных ключей

Высока вероятность, что на данном этапе вам не понадобится инкрементальная модель.
Руководство по передовому опыту dbt говорит:

Начните как можно проще

  • 🔍Начните с вида. Когда представление становится слишком длинным для запроса конечных пользователей,
  • ⚒️Сделайте стол. Когда таблица становится слишком длинной, чтобы в нее можно было встроить задания dbt,
  • 📚Создавайте его постепенно. То есть располагайте данные порциями по мере их поступления.

Так что сейчас самое время задуматься о переходе на инкрементный режим, когда выполнение dbt становится слишком долгим и тяжелым. При этом к генерации суррогатных/первичных/инкрементных ключей это не имеет никакого отношения.


Несколько примечаний:

  • ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername)) может быть подвержено ошибкам. Потому что в разное время суррогатный_ключ может иметь разные значения для одной и той же клиентской кампании. Если возможно, добавьте временную метку ROW_NUMBER() OVER (ORDER BY c.clientcode, c.adservername, c.campaign_created_timestamp))
  • Прочтите этот пост о том, почему лучше избегать автоинкрементного идентификатора в dbt: ссылка
  • Возможно, вы захотите изменить свой суррогатный ключ с помощью хеша. Вот почему это выгодно. И вот удобный макрос от dbt_utils, более надежный, чем md5

Другие вопросы по теме

Похожие вопросы

Как правильно подсчитывать операции (временную сложность) в алгоритме пузырьковой сортировки в Python
Я пытаюсь использовать Scrapy Drumwright, чтобы пролистать интернет-магазин и собрать все товары, но это не работает
Как я могу удалить только отдельные строки между текстом, чтобы разбить его на части?
DuckDB вставляет разделы куста в файл паркета
Pydantic ConfigDict(use_enum_values=True) не оказывает никакого эффекта при предоставлении значения по умолчанию. Как я могу предоставить значения по умолчанию?
Недостаточно памяти при запуске модели MIP в Python с пакетом Gurobi
Как получить данные с веб-страницы, которая не отвечает на GET
Как удалить первые n строк в пандах на основе условия, оставив остальную часть данных нетронутой
Быстрое получение кода состояния 2000 URL-адресов и сохранение их в виде словарного вывода
Как удалить новую строку (строки) из длинной строки