Код-ревью Middle dbt обновлено

Код-ревью: инкрементальная модель dbt

Вопрос

Аналитик прислал модель витрины платежей. Найдите проблемы.

{{ config(materialized='incremental') }}

select
    p.payment_id,
    p.user_id,
    u.country,
    p.amount / 100 as amount_rub,
    p.paid_at
from analytics.raw_payments p
left join {{ ref('dim_users') }} u on u.user_id = p.user_id
where p.status = 'success'
{% if is_incremental() %}
  and p.paid_at > (select max(paid_at) from {{ this }})
{% endif %}

Коротко

Модель «работает», но тихо теряет и задваивает данные. Минимальный набор правок: source или staging, uniquekey, фильтр по времени изменения с окном запаса, явное приведение типов, хранение статуса вместо фильтрации на входе.

Что должен найти ревьюер

  1. Ошибкастрока 1
    Инкрементальная модель без unique_key: повторно обработанные строки задвоятся, а изменения статуса уже загруженных платежей не применятся.
  2. Ошибкастрока 9
    Сырая таблица указана напрямую analytics.raw_payments вместо source() или staging-модели: нет lineage, проверки свежести и подстановки окружения.
  3. Ошибкастрока 7
    amount / 100 при целочисленном amount в части хранилищ делает целочисленное деление и теряет копейки. Нужно amount / 100.0 или явное приведение к numeric.
  4. Ошибкастрока 13
    Фильтр > max(paid_at) теряет опоздавшие платежи и платежи, сменившие статус на success позже. Нужен фильтр по времени обновления с окном запаса.
  5. Ошибкастрока 11
    Фильтр по статусу success в инкрементальной модели: если платёж потом вернули, строка останется в витрине. Нужно хранить статус и фильтровать в потребителях или обрабатывать изменения.
  6. Стильстрока 6
    Страна пользователя берётся текущая, а не на момент платежа: при переезде пользователя исторические платежи «переедут». Если важно, нужен point-in-time join со снапшотом.

Разбор

Модель «работает», но тихо теряет и задваивает данные. Минимальный набор правок: source или staging, unique_key, фильтр по времени изменения с окном запаса, явное приведение типов, хранение статуса вместо фильтрации на входе. И тесты: unique и not_null на payment_id, relationships на пользователя.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.