Дата-инженерия
Роль одним абзацем: аналитик отвечает на вопросы, а дата-инженер делает так, чтобы данные сами приезжали, чистились и обновлялись — надёжно и без ручного участия. Это про воспроизводимость, реальный 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 вообще стоит.
Скрипт + окружение
пара вечеровОдин .py, который поднимается у любого из чистого окружения. Это фундамент воспроизводимости, всё остальное растёт отсюда.
- Поднимаешь изолированное окружение (venv/uv) и фиксируешь зависимости с пиннингом версий
- Держишь код в Linux-ФС внутри WSL, а не в /mnt/c, и понимаешь, почему так быстрее
- Прячешь секреты в .env, а .env, .venv и data держишь вне гита через .gitignore
- Ведёшь git осмысленно: понятные коммиты, ветки под задачи, внятный README
- Проект запускается на чужой машине без «а тут допиши руками»
Данные из API → хранилище
1–2 неделиНаучиться тянуть данные самому и класть их в базу, а не в CSV на рабочем столе.
- Проходишь всю пагинацию (page / offset / cursor), а не только первую страницу
- Авторизуешься по токену и держишь ключ вне кода, в окружении
- Ставишь ретраи с exponential backoff и уважаешь rate limit — 429/5xx не роняют сбор
- Пишешь результат в DuckDB/Postgres и умеешь глянуть таблицы в DBeaver
- Повторный запуск не плодит дубли — делаешь upsert/merge по ключу
Трансформации в dbt
2–3 неделиПревратить сырые таблицы в чистые витрины — как код, с тестами, документацией и lineage.
- Строишь слои staging → marts и связываешь модели через ref() и source()
- Покрываешь ключевые колонки тестами (unique, not_null) — и они зелёные
- Делаешь хотя бы одну инкрементальную модель с корректным фильтром is_incremental()
- Генерируешь документацию и читаешь по ней lineage — откуда взялась каждая цифра
- Осознанно выбираешь материализацию (view / table / incremental) под задачу
Инжест по-взрослому · dlt
2–3 неделиЗаменить самописные скрипты на инструмент, который сам держит схему и инкремент.
- Оформляешь источники как dlt-ресурсы и грузишь их несколькими строками питона
- Настраиваешь write_disposition (append / replace / merge) под задачу
- Ведёшь инкремент по курсору без ручной возни со схемой
- Разворачиваешь вложенный JSON в плоские таблицы автоматически
- Меняешь destination (например, DuckDB ↔ Postgres) почти без правок кода
Оркестрация и расписание
3–4 неделиСвязать шаги в единый процесс, поставить на расписание, добавить ретраи и алерты.
- Описываешь пайплайн как flow/DAG с явными зависимостями между шагами
- Ставишь на расписание и умеешь прогнать бэкфилл за пропущенные даты
- Вешаешь ретраи на нестабильные шаги вместо «перезапущу руками»
- Ловишь падение и получаешь алерт — не узнаёшь о сбое от пользователей
- Читаешь логи и историю запусков в UI и видишь, что именно где упало
Контейнеры и прод
финиш · боевой стекУпаковать весь стек так, чтобы он поднимался одной командой где угодно.
Финиш: docker compose up — и весь дата-стек поднимается с нуля.
- Пишешь Dockerfile для своего пайплайна и собираешь рабочий образ
- Поднимаешь мультисервис (база + оркестратор + BI) через compose с depends_on
- Весь стек стартует одной командой из чистой машины
- Секреты и конфиги вынесены в окружение — ничего не зашито в образ
- Есть тесты данных и базовая наблюдаемость: логи, статусы, алерты
- Проект оформлен так, что его не стыдно показать работодателю