ветка · ★★☆

Дата-инженерия

Роль одним абзацем: аналитик отвечает на вопросы, а дата-инженер делает так, чтобы данные сами приезжали, чистились и обновлялись — надёжно и без ручного участия. Это про воспроизводимость, реальный open-source стек и архитектуры, которые не разваливаются при перезапуске. Ключевая мысль: момент, когда аналитик становится инженером, — это когда «работает у меня на ноуте» превращается в «работает у всех и по расписанию».

чем занимаешься

На практике ты строишь конвейер сырое → чистое → витрина: тянешь данные из API, баз и файлов, складываешь в хранилище, преобразуешь SQL-моделями с тестами и документацией, ставишь всё на расписание с зависимостями, ретраями и алертами, а потом упаковываешь стек в контейнеры, чтобы он поднимался одной командой где угодно.

стек

Среда: WSL2 + venv/uv + Docker/docker-compose. Python для данных: pandas/polars, requests/httpx, tenacity. Загрузка: dlt (плюс Airbyte, Kafka/Redpanda для стриминга). Трансформации: dbt Core (плюс SQLMesh). Хранилища: DuckDB, Postgres, ClickHouse, BigQuery/Snowflake. Форматы и озеро: Parquet, Iceberg на MinIO/S3. Оркестрация: Prefect, Airflow, Dagster, Kestra. BI: Metabase, Superset, Lightdash, Grafana, семантический слой Cube и Streamlit.

кому заходит

Заходит тем, кому уже мало «отвечать на вопросы по готовым данным» — хочется строить сам конвейер. Кто любит порядок, автоматизацию и инженерию, кайфует, когда что-то крутится само. Классический следующий шаг для аналитика, который дорос до инженера, и для бэкендера, которого потянуло в данные.

чем отличается

Аналитик работает с уже подготовленными данными — вопросы, дашборды, SQL, статистика — и не владеет «трубопроводом». Дата-инженер (это ты) строит и держит сам трубопровод: надёжную доставку и обновление данных, чтобы у аналитика всегда было на чём работать. ML-инженер берёт подготовленные данные и учит на них модели и фичи — твои пайплайны это тот фундамент, на котором ML вообще стоит.

0

Скрипт + окружение

пара вечеров

Один .py, который поднимается у любого из чистого окружения. Это фундамент воспроизводимости, всё остальное растёт отсюда.

инструмент WSL2, venv или uv, git, requirements.txt / pyproject, .env для секретов датасет Любой открытый источник по интересам — CSV/JSON на тему, которую реально хочется ковырять: спорт, музыка, игры, крипта, кино.
что делаешь Скрипт + README + requirements.txt, который поднимается «с нуля» короткой серией команд на любой машине.
Готов дальше, когда:
  • Поднимаешь изолированное окружение (venv/uv) и фиксируешь зависимости с пиннингом версий
  • Держишь код в Linux-ФС внутри WSL, а не в /mnt/c, и понимаешь, почему так быстрее
  • Прячешь секреты в .env, а .env, .venv и data держишь вне гита через .gitignore
  • Ведёшь git осмысленно: понятные коммиты, ветки под задачи, внятный README
  • Проект запускается на чужой машине без «а тут допиши руками»
1

Данные из API → хранилище

1–2 недели

Научиться тянуть данные самому и класть их в базу, а не в CSV на рабочем столе.

инструмент requests/httpx, tenacity для ретраев, DuckDB или Postgres, DBeaver под рукой датасет API любимого сервиса — то, что тебе интересно: игровая статистика, погода, транзакции, треки, репозитории.
что делаешь Скрипт: API → таблица в базе, повторяемый и без дублей при перезапуске.
Готов дальше, когда:
  • Проходишь всю пагинацию (page / offset / cursor), а не только первую страницу
  • Авторизуешься по токену и держишь ключ вне кода, в окружении
  • Ставишь ретраи с exponential backoff и уважаешь rate limit — 429/5xx не роняют сбор
  • Пишешь результат в DuckDB/Postgres и умеешь глянуть таблицы в DBeaver
  • Повторный запуск не плодит дубли — делаешь upsert/merge по ключу
2

Трансформации в dbt

2–3 недели

Превратить сырые таблицы в чистые витрины — как код, с тестами, документацией и lineage.

инструмент dbt Core, движком под ним — Postgres или DuckDB датасет Те же сырые данные, что уже лежат в базе с прошлого уровня — превращаешь их в осмысленные метрики по своей теме.
что делаешь Слой staging → marts со связями через ref()/source(), тестами и авто-документацией с графом зависимостей.
Готов дальше, когда:
  • Строишь слои staging → marts и связываешь модели через ref() и source()
  • Покрываешь ключевые колонки тестами (unique, not_null) — и они зелёные
  • Делаешь хотя бы одну инкрементальную модель с корректным фильтром is_incremental()
  • Генерируешь документацию и читаешь по ней lineage — откуда взялась каждая цифра
  • Осознанно выбираешь материализацию (view / table / incremental) под задачу
3

Инжест по-взрослому · dlt

2–3 недели

Заменить самописные скрипты на инструмент, который сам держит схему и инкремент.

инструмент dlt: resources, write_disposition, инкремент по курсору, авто-нормализация JSON датасет Несколько источников по интересам на одну тему — пара API плюс выгрузка из БД или файлов.
что делаешь Пайплайн dlt: несколько источников → warehouse с инкрементом и авто-схемой.
Готов дальше, когда:
  • Оформляешь источники как dlt-ресурсы и грузишь их несколькими строками питона
  • Настраиваешь write_disposition (append / replace / merge) под задачу
  • Ведёшь инкремент по курсору без ручной возни со схемой
  • Разворачиваешь вложенный JSON в плоские таблицы автоматически
  • Меняешь destination (например, DuckDB ↔ Postgres) почти без правок кода
4

Оркестрация и расписание

3–4 недели

Связать шаги в единый процесс, поставить на расписание, добавить ретраи и алерты.

инструмент Prefect для старта, Airflow вторым (его чаще спрашивают); Dagster и Kestra — на посмотреть датасет Тот же конвейер по твоей теме, что уже собран, — но теперь он запускается сам, по расписанию.
что делаешь dlt → dbt → BI по расписанию с уведомлением при сбое и историей запусков в UI.
Готов дальше, когда:
  • Описываешь пайплайн как flow/DAG с явными зависимостями между шагами
  • Ставишь на расписание и умеешь прогнать бэкфилл за пропущенные даты
  • Вешаешь ретраи на нестабильные шаги вместо «перезапущу руками»
  • Ловишь падение и получаешь алерт — не узнаёшь о сбое от пользователей
  • Читаешь логи и историю запусков в UI и видишь, что именно где упало
5

Контейнеры и прод

финиш · боевой стек

Упаковать весь стек так, чтобы он поднимался одной командой где угодно.

инструмент Docker + docker-compose, плюс тесты данных и базовая наблюдаемость датасет Весь твой end-to-end кейс на выбранной теме, целиком в контейнерах — например, локальный современный дата-стек.
что делаешь Весь пайплайн в docker-compose: база + оркестратор + BI, задеплоено и воспроизводимо.

Финиш: docker compose up — и весь дата-стек поднимается с нуля.

  • Пишешь Dockerfile для своего пайплайна и собираешь рабочий образ
  • Поднимаешь мультисервис (база + оркестратор + BI) через compose с depends_on
  • Весь стек стартует одной командой из чистой машины
  • Секреты и конфиги вынесены в окружение — ничего не зашито в образ
  • Есть тесты данных и базовая наблюдаемость: логи, статусы, алерты
  • Проект оформлен так, что его не стыдно показать работодателю