dbt sources и macros на собеседовании Data Engineer
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем спрашивают на собесе DE
dbt — стандарт T в ELT. На собесе DE: «зачем sources», «как написать macro», «freshness».
Sources и ref
Source — внешняя таблица (raw layer), не управляемая dbt.
# sources.yml
sources:
- name: raw_app
schema: raw
tables:
- name: users
columns:
- name: id
tests: [unique, not_null]
- name: eventsВ моделях:
SELECT * FROM {{ source('raw_app', 'users') }}Ref — ссылка на другую модель.
SELECT * FROM {{ ref('stg_users') }}dbt автоматически строит DAG зависимостей через ref.
Source freshness
Проверка, что source данные не устарели.
sources:
- name: raw_app
tables:
- name: events
loaded_at_field: created_at
freshness:
warn_after: {count: 12, period: hour}
error_after: {count: 24, period: hour}dbt source freshness — проверяет.
Если created_at старше 24 часов — error в pipeline.
Macros и Jinja
dbt SQL — это Jinja-templated SQL.
SELECT *
FROM {{ ref('orders') }}
WHERE created_at >= '{{ var("start_date") }}'var() — переменные.
Условная логика:
{% if target.name == 'prod' %}
AND env = 'production'
{% ELSE %}
AND env = 'staging'
{% endif %}Loops:
{% for col IN ['name', 'email', 'phone'] %}
COALESCE({{ col }}, '') AS {{ col }}_clean,
{% endfor %}Custom macros
Reusable SQL snippets.
-- macros/cents_to_dollars.sql
{% macro cents_to_dollars(column_name) %}
({{ column_name }} / 100.0)::NUMERIC(10, 2)
{% endmacro %}Использование:
SELECT
order_id,
{{ cents_to_dollars('amount_cents') }} AS amount_dollars
FROM {{ ref('orders') }}dbt_utils package. Стандартные макросы:
dbt_utils.surrogate_key([col1, col2])— hash composite key.dbt_utils.pivot(),unpivot().dbt_utils.deduplicate().dbt_utils.union_relations().
Hooks
Запуск SQL до / после dbt операций.
Pre-hook / post-hook (model-level):
{{ config(
pre_hook="GRANT SELECT ON {{ this }} TO analyst_role",
post_hook="VACUUM ANALYZE {{ this }}"
) }}On-run-start / on-run-end (project-level в dbt_project.yml):
on-run-start: "CREATE SCHEMA IF NOT EXISTS {{ target.schema }}"
on-run-end: "GRANT USAGE ON SCHEMA {{ target.schema }} TO analyst_role"Частые ошибки
Hard-coded имена таблиц. Без ref() / source() — dbt не знает зависимости. Lineage ломается.
Macros без документации. Через год команда не помнит, что делает custom macro.
Слишком сложные macros. Если macro имеет 50 строк — может быть отдельная модель.
Игнорировать freshness. Stale data загружается в downstream — никто не замечает.
Hard-coded environments в Jinja. Используй target.name или vars.
Не запускать dbt_utils тесты. Дублирование собственных тестов на каждую модель — лишний труд.
Связанные темы
- dbt на собесе DE
- dbt incremental models для DE
- dbt snapshots для DE
- Great Expectations для DE
- Подготовка к собесу Data Engineer
FAQ
Macros vs models?
Macro — reusable SQL fragment. Model — таблица / view. Если SQL генерирует data — model. Если transforms существующий — macro.
Это официальная информация?
Нет. Статья основана на документации dbt 1.7+.
Тренируйте Data Engineering — откройте тренажёр с 1500+ вопросами для собесов.