rzv Data Engineering
2.76K subscribers
153 photos
2 files
89 links
Авторский канал о том, как я понимаю инжиниринг данных. Объясняю термины, best practice, делюсь описанием рабочих задачек. См закрепы

Рассчитан на новичков в DE и инженеров до Senior.

Чат: t.me/+jtQ1tjvNUtwzN2My
По вопросам: @razvodov_de_mentor
Download Telegram
С какими трудностями можно столкнуться на первой задаче на первой работе 3/?
Масштаб

🔸 Pull Request создан. Но вместо кнопки Merge — красное предупреждение: conflict.

Пока ты ждал доступы и разбирался в структуре репозитория, кто-то из команды поменял тот же SQL-файл. Гуглишь "how to resolve merge conflict", читаешь документацию, аккуратно вливаешь чужие изменения. Получилось. Выдыхаешь.
Но тут приходит мысль: "А это поле точно нужно только в одной табличке?"

Открываешь IDE: и ищешь таблицу по всем файлам через Cmd+Shift+F. Один файл, второй, пятый... Оказывается, staging-таблица — это только начало цепочки. Дальше данные текут в 5 таблиц в Greenplum, оттуда — в 2 витрины в ClickHouse, и уже потом — на дашборды.

🔸 "Мне нужно поправить это везде?"

Пишешь в чат команды. Пальцы немного замирают перед отправкой — вдруг глупый вопрос? Отправляешь. Через пять минут приходит ответ:

"Хороший вопрос, Кеша, давай разберёмся вместе".

Оказывается, нужно ещё уведомить владельцев промежуточных таблиц, что у них появится новое поле.

Первый урок: задавать вопросы — это часть работы, могут всплыть полезные вводные.

Вечером приходит письмо: "Ваша заявка на доступ одобрена"...
👍643
С какими трудностями можно столкнуться на первой задаче на первой работе 4/?
Сюрпризы

🔸 Наконец-то! Подключаешься к источнику, находишь нужную таблицу, делаешь select distinct по новому полю.
И видишь: '123', '456', 'None', '789'...
Числа хранятся как текст. А вместо null — строка 'None'. Классика.

Значит, при загрузке нужно добавить приведение типа и обработку этих "None". Не сложно, но об этом нигде не было написано. Добавляешь nullif(trim(field), 'None')::integer в SQL и чувствуешь себя немного детективом.

🔸 Пока правишь код, вспоминаешь про вопрос: это поле нужно протянуть во все 7 таблиц или только в финальную витрину? Уже вечером напоминаешь заказчику лично в Mattermost. Ответ приходит на следующий день:

"Спасибо за напоминание) Давай только в витрину и 'наши' таблицы в схеме 'marketing', остальным командам оно не нужно".


Смотришь на код, который уже поменял для всех семи таблиц. Возвращаешь назад большую часть. Смешанные чувства — вроде зря потратил время, но хотя бы исправил до релиза. "Ладно, осталось залить исторические данные..."
👍101
С какими трудностями можно столкнуться на первой задаче на первой работе 5/?
Backfill

🔸 Поле добавлено в код, но в таблице на Dev — данные за последние полгода без него. Нужно пересчитать историю.
Идёшь на корпоративную вики искать инструкцию по backfill. Находишь страницу "Как запустить backfill в Airflow". Дата последнего обновления: март 2022. Половина скриншотов не соответствует текущему интерфейсу.

Пишешь в чат: "Ребят, а актуальная инструкция по backfill есть?"
Скидывают ссылку на другую страницу. Там чуть лучше, но всё равно приходится разбираться методом тыка: какие параметры передать, как выбрать интервал дат, что будет, если запустить повторно.

🔸 Решаешь подстраховаться — сначала запуск на один день. Смотришь в логи. Работает. Данные на месте.

Теперь полный backfill: 6 месяцев, сотни однодневных партиций. Нажимаешь кнопку и идёшь за кофе. Возвращаешься через пять минут — прогресс 7%. Следующий час периодически обновляешь страницу с логами.

Готово. Данные залились. Обновляешь Pull request. Можно выдохнуть и двигаться дальше — осталось пройти code review...
👍6
С какими трудностями можно столкнуться на первой задаче на первой работе 6/?
Ревью

🔸 Pull Request обновлён, конфликты разрешены, backfill завершён. Назначаешь ревьюера и ждёшь.

День проходит. Параллельно разбираешься с тестированием: count'ы в источнике и приёмнике должны сходиться, data quality checks — гореть зелёным.

На второй день пишешь в личку:

"Привет! Сможешь глянуть PR? Ссылка: https://..."

Оказывается, ревьюер был в отпуске и только вышел. Обещает посмотреть сегодня.

🔸 Вечером прилетает уведомление: 14 комментариев.

"Давай переименуем переменную по нашему code style", "Здесь лучше использовать CTE вместо подзапроса", "А почему не добавил тест?", "Кеш, минорно -- опечатка в комментарии"...

Первая реакция — хочется обидеться. Потом понимаешь: это не критика тебя лично, это про качество кода и договорённости в команде, к которым пока не привык. Садишься править.
Первый раунд правок — готово. Ещё 3 комментария. Исправляешь. Ещё один.

🔸 Заодно заранее предупреждаешь BI-щика, что нужно будет добавить новое поле в запрос дашборда. Доступов у тебя пока нет, но ты понял что при помощи коллег можно сделать больше. Предупреждаешь, что добавить поле нужно будет после развёртывания правок из PR, иначе упадёт с ошибкой. И кидаешь ещё одну заявку на недостающий доступ.

Утром видишь заветное: Approved.
Merge. Деплой. Осталось проверить на проде...
👍5
С какими трудностями можно столкнуться на первой задаче на первой работе 7/7
Рефлексия

🔸 Код в main ветке, CI/CD отработал, изменения на проде. Теперь нужно запустить backfill в production Airflow.
Открываешь ссылку на Airflow — "Access denied". Нет доступов к виртуальным машинам прода.

Ещё одна заявка. Но ждать некогда — хочется довести задачу до конца. Пишешь тимлиду:

"Можешь запустить вот эту команду? Протестировал на dev, работает".


Тимлид на встрече. Пока ждёшь, напоминаешь BI-щику про его часть.

Ответ от лида через час:

"Запустил".


🔸 Ждёшь. Обновляешь дашборд. Пусто. Ещё раз. Пусто. "Что не так?" — начинается лёгкая паника.

Потом вспоминаешь: backfill пайплайн на деве работал довольно долго, а на проде данных за 3 года. Данные появятся утром.

Утро. Открываешь дашборд. Поле на месте. Значения корректные. Никаких ошибок (ну давайте Кеше один раз сильно повезёт)

Тихая победа. Без фанфар, без аплодисментов. Просто новая колонка в отчёте, на которую посмотрит аналитик и даже не задумается, сколько всего за ней стояло.

🔸 Смотришь на даты в трекере задач: задача была создана 8 рабочих дней назад. "Протянуть одно поле". Теперь ты знаешь: первая задача — это не про код. Это про систему, про людей, про процессы. Про умение задавать вопросы и ждать доступы. Про merge conflicts и устаревшую документацию.

Кеша справился. И ты справишься!

---

Если чувствуешь, что на испыталке пригодится поддержка — пиши в личку ;)
🔥34
rzv Data Engineering
Разыгрываю 26% скидки к предоплате и постоплате на помощь с переходом в Data Engineering. С твоего уровня до конца испытательного срока 🔸 Помогу: - понять, подойдёт ли тебе дата инжиниринг - определить текущий уровень - наработать недостающие навыки - подготовить…
А ещё напоминаю про конкурс комментариев. Пока даже никакой интриги нет)

Участвуй, если:
- не хочешь самостоятельно разбираться с изменениями нейронайма (рекрутеры тоже пользуются AI)
- хочешь обогнать тех, кто отрицает текущие "правила игры"
- долго откладываешь и сомневаешься, а не стало ли уже слишком поздно
- пробовал(а) разобраться сам(а) и "затянуло в трясину" вечной подготовки
- хорошо с математикой: с оффером в 200 тыс рублей экономия (20т + 200т *1.75) - (20т *0.74 + 200т *1.49) = 57.2т
- кажется, если IT это не для тебя и ты не справишься -- созвонимся и обсудим эти переживания

В общем, осталось 6 часов, действуй)
rzv Data Engineering
Разыгрываю 26% скидки к предоплате и постоплате на помощь с переходом в Data Engineering. С твоего уровня до конца испытательного срока 🔸 Помогу: - понять, подойдёт ли тебе дата инжиниринг - определить текущий уровень - наработать недостающие навыки - подготовить…
🐇 Результаты розыгрыша!

🔸 Поздравляю победителей:
@rabsiyanin - подробно расписал, к чему хочет прийти и почему для него это важно
@DataResearcher - уже есть опыт собеседований, нужно помочь дорасти до миддла и стать самостоятельным DE, искренне признал личную ошибку
@Pavel_Big_Data - описал самостоятельно пройденный путь, знает что хочет взять от меня и не боится это просить

🔸 Остальным участникам скидка 26% на предоплату и фидбэк. Записывайся до 1 февраля на звонок через форму на сайте, обсудим, чем я смогу помочь:
@IKiseleff - желания разобраться недостаточно; не вложил время чтобы выделиться среди остальных людей
@m_vladislav1 - самоуверенные заявления про будущий успех без аргументов; для того чтобы написать коммент первым нужна определённая смелость, но этого мало; нет контекста, целей, не вижу мотивацию
@sevazhe - про “судьбу” лично в меня не попало, нет контекста, целей, не вижу мотивацию
@mvbashkirovv - запрос прояснить ожидания от перехода в DE поддерживаю, буду рад встретиться на первом звонке; но для меня ненадёжно отдавать тебе призовое место — если поймёшь, что не твоё, придётся искать ещё одного победителя; мотивация других оказалась сильнее
@egorbeloz - чувство юмора это хорошо, участие принял) но другие постарались больше
@Worldsenar - мне не понравилась аргументация в стиле “я точно справлюсь, потому что любые преграды мне по плечу”

🔸 Бонус:
всем подписчикам этого канала
скидка на предоплату 13%

Чтобы её закрепить за собой, прочти условия на сайте rzvde.pro и напиши в личку

код RZVDE26JAN

Это нужно сделать до окончания 7 января по мск
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥31
Живой пример моделирования данных с SCD2 в аналитике небольшой учебной платформы 1/2

🔸 Слыхали про “Data-driven decision making”? Я вдохновился этим подходом ещё когда только начинал свой путь в данные. Сейчас учусь применять для принятия своих решений.

Допустим, я строю свою образовательную платформу и хочу собирать статистику для дашбордов. У меня пока ничего нет, в будущем нужно получить ответы на вопросы:

1. сколько дней занимает прохождение каждого из этапов подготовки у каждого менти?
2. а максимум, минимум, в среднем?
3. сколько клиентов сейчас на этом этапе?
4. кто сейчас на каком этапе?
5. у клиентов из более поздних групп больше или меньше времени уходит на те же этапы подготовки?


🔸 Какие данные собирать? В каком виде? Как уменьшить усилия и передать максимум "автоматике"?

Выделю сущности и их минимально необходимые атрибуты:

client_dict:
⁃ tg_nickname (key)
⁃ group_num

client_x_stage:
⁃ tg_nickname
⁃ stage_start_date
⁃ stage_name

stage_dict:
⁃ stage_name (key)
⁃ is_final


Этапы примерно такие, для упрощения добавлю номера прям в названия:
⁃ “1 начал изучение материалов”
⁃ “2 подготовка резюме”
⁃ “3 собеседуется”
⁃ “4 на испытательном сроке”
⁃ “5 прошёл испыталку”

В этапы входят так же статусы вроде “бросил обучение”, “на паузе”, “размышляет после вводного звонка”, но для упрощения оставим их в стороне.

🔸 Для получения ответов на вопросы достаточно заполнить справочники client_dict, stage_dict, и вести лог client_x_stage. А всё остальное можно достать относительно базовым SQL, я уложился в сотню строчек с комментами.

🔙 Покрути запросы в песочнице и попробуй ответить на вопросы выше, завтра поделюсь своим вариантом решения.
https://www.db-fiddle.com/f/29bwADFGc65Seh3Vv5Z9ac/1

p.s. я знаю, что лучше добавить суррогатные ключи для сущностей и связывать через них, это минимально рабочий пример
p.p.s тот же DDL + DML для надёжности прикладываю файликом
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥72
Живой пример моделирования данных с SCD2 в аналитике небольшой учебной платформы 2/2

А вот мой вариант решения
https://www.db-fiddle.com/f/iG51oyoBWkfK9q1HdFUuyz/0

🔸 Что хорошо:
- некоторые запросы можно (и нужно) переиспользовать
- данные честные, с учётом нюансов (не учитываюся те, кто ещё не завершил этап)
- с небольшой доработкой можно учесть случаи вроде "возвращения на предыдущий этап" или "бросил обучение"
- автоматизирован максимум того, что можно вычислить -- не нужно обновлять какие-то данные руками
- даёт наглядную статистику в табличках, к которым легко подключить дашборды

p.s. Текущая версия работает в google sheets + data lens = никакой бигдаты :(

p.p.s. Зато быстрое прототипирование и удобный ввод данных :)

p.p.p.s. Тот самый случай, когда "временное решение" остаётся надолго и становится основным
👍6🔥31
rzv Data Engineering
#вести_с_полей Напоминалка про NULL в sql Null не содержит значения (мы не знаем, какое значение атрибута было "в том месте и в то время"), но хранит тип данных. На продакшене, если добавляешь новую колонку "на будущее" или гармонизируешь данные из разных…
Как тебе последние посты? Больше такого или меньше? Пиши в комменты

Самый популярный за прошлый год -- про типы данных в NULL, может делать более прикладной контент?)

До "в чём разница между HAVING и WHERE" скатываться не буду)

upd: а 👍 это "больше такого" делать или "меньше, лучше попроще"?)

upd2: а ты сходи и на посты выше пореагируй активнее, чтобы я понял что тебе такое нравится и такого надо больше)
👍35🤔1