Код-ревью 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Инкрементальная модель без
unique_key: повторно обработанные строки задвоятся, а изменения статуса уже загруженных платежей не применятся. - Ошибкастрока 9Сырая таблица указана напрямую
analytics.raw_paymentsвместоsource()или staging-модели: нет lineage, проверки свежести и подстановки окружения. - Ошибкастрока 7
amount / 100при целочисленномamountв части хранилищ делает целочисленное деление и теряет копейки. Нужноamount / 100.0или явное приведение к numeric. - Ошибкастрока 13Фильтр
> max(paid_at)теряет опоздавшие платежи и платежи, сменившие статус на success позже. Нужен фильтр по времени обновления с окном запаса. - Ошибкастрока 11Фильтр по статусу success в инкрементальной модели: если платёж потом вернули, строка останется в витрине. Нужно хранить статус и фильтровать в потребителях или обрабатывать изменения.
- Стильстрока 6Страна пользователя берётся текущая, а не на момент платежа: при переезде пользователя исторические платежи «переедут». Если важно, нужен point-in-time join со снапшотом.
Разбор
Модель «работает», но тихо теряет и задваивает данные. Минимальный набор правок: source или staging, unique_key, фильтр по времени изменения с окном запаса, явное приведение типов, хранение статуса вместо фильтрации на входе. И тесты: unique и not_null на payment_id, relationships на пользователя.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.