Как пройти маршрут
Начинайте без опыта в профессии. Результат маршрута — конвейер с повторяемой загрузкой, тестами, витриной и восстановлением после сбоя. Переходите дальше, когда можете выполнить задание и объяснить результат.
Здесь 19 основных шагов и 3 шага углубления. Это самостоятельная часть единой программы аналитических профессий: другие карты проходить заранее не нужно. Разделы с одинаковой базой можно пропустить только после решения их задания без подсказки. Фиксированного срока и гарантии трудоустройства нет.
Работайте в цикле: прочитайте объяснение → попробуйте пример → выполните задание → откройте разбор → исправьте ошибку → сохраните результат. Одна отметка может потребовать нескольких занятий. Записывайте время и трудности первых трёх шагов, затем планируйте посильный темп. Обязательные задания основной части выполняются бесплатно. Для локальных программ нужен компьютер; ограничения ОС и доступа указаны в шагах.
Кейс «Круг» и данные вымышлены. На маленькой таблице удобно проверить вычисления руками; она не доказывает спрос, причинность или качество ML-модели. В самостоятельном проекте предстоит изменить данные и требования. Не загружайте реальные персональные или рабочие данные в публичные тренажёры.
Основной текст русский. Для английской документации ведите словарь: термин, смысл своими словами, пример. Перевод браузера допустим, но названия полей и код не переводите. Начните с одного абзаца документации за занятие и постепенно переходите к самостоятельному чтению.
Шаг 1. Подготовить рабочее место и словарь
Разберём на примере
Сервис «Круг» сдаёт учебные комнаты по времени. Это вымышленный кейс: все числа и записи созданы для обучения. Начните с файлов, чтобы уметь повторить работу на другом компьютере. CSV — текстовая таблица: первая строка содержит имена столбцов, последующие строки — записи. Расширение файла обозначает его формат; переименование картинки в CSV таблицу не создаёт. В наших данных одна строка — одно бронирование, суммы хранятся целым числом евроцентов, даты — как год-месяц-день.
Скачать вымышленные бронирования (CSV). Для SQL позже понадобится готовая схема и те же строки.
Что прочитать и посмотреть
- LibreOffice: CSV — Импорт CSV: разделитель, кодировка и типы столбцов. Бесплатная справка, английский; приложение LibreOffice бесплатно.
Что сделать
- Создайте папку krug и внутри raw, work, results. Скачайте bookings.csv по ссылке в этом разделе и сохраните в raw; исходник больше не редактируйте.
- Откройте CSV в LibreOffice Calc: кодировка UTF-8, разделитель — запятая. Проверьте восемь столбцов и шесть строк данных. Сохраните рабочую копию в work в формате ODS.
- Создайте словарь с полями: столбец, смысл, тип, допустимые значения, единица измерения. Запишите вопросы о неизвестных правилах; не подставляйте догадки.
Что сохранить
Таблица, словарь восьми полей и журнал вопросов в results.
Как проверить себя
Снова откройте сохранённую таблицу. Идентификаторы u1 и A сохранились как текст, суммы 2000 не превратились в 20. Дата читается однозначно.
Разбор — откройте после своей попытки
booking_id обозначает бронирование; user_id — учебный код пользователя, room_id — комнату. minutes — длительность забронированного интервала. Для cancelled она не означает фактическое использование. Словарь должен прямо говорить об этом. Файл содержит 6 бронирований, но только 4 разных пользователя.
Шаг 2. Написать первые программы на Python
Разберём на примере
Программа выполняет инструкции по порядку. Переменная связывает имя со значением; список хранит несколько значений; цикл повторяет действия. Условие if выбирает ветку. Функция объединяет действия и возвращает результат через return. Начните без библиотек: аналитик или инженер должен понимать, что происходит с одной записью, до обработки тысяч строк. Текст "2000" и число 2000 имеют разные типы; преобразование int может завершиться ошибкой, если текст не является числом.
Что прочитать и посмотреть
- Основы Python — Яндекс Образование — Темы ввода и вывода, условий, циклов, коллекций и функций: решайте задачи по порядку до уверенного решения без подсказки. Бесплатный текст на русском; тренажёр может потребовать аккаунт.
- Учебник Python — Разделы An Informal Introduction, More Control Flow Tools, Data Structures и Errors and Exceptions. Бесплатно, английский; это справочник после первых упражнений, а не единственное объяснение с нуля.
Что сделать
- Пройдите темы ввода, условий, циклов, списков и функций в русскоязычном учебнике. Решите минимум по три задачи каждой темы самостоятельно.
- Напишите функцию net(charged, refund), которая возвращает разность. Для списка пар [(2000,0),(3000,1000),(0,0)] получите общий итог.
- Добавьте проверки: refund неотрицателен и не больше charged. Для неверных данных выдавайте ValueError с понятным сообщением. Проверьте ноль, полный возврат и возврат больше оплаты.
Что сохранить
Файл basics.py, пять коротких примеров вызова и объяснение одной ошибки.
Как проверить себя
Итог примера равен 4000. net(0,0) возвращает 0, net(2000,2000) — 0, net(100,200) сообщает об ошибке.
Разбор — откройте после своей попытки
Внутри функции сначала проверьте if charged < 0 or refund < 0 or refund > charged: raise ValueError("Некорректный возврат"). Затем return charged-refund. Общий итог получите циклом с накоплением. В таком виде правило допускает полный возврат и запрещает превышение оплаты.
Шаг 3. Запускать код в отдельном окружении и хранить версии
Разберём на примере
Окружение отделяет библиотеки проекта от других программ. Терминал — окно для текстовых команд; его текущая папка определяет, где создаются файлы. Git сохраняет историю изменений: commit — именованный снимок выбранных файлов. Репозиторий может оставаться на компьютере, публикация не требуется. Для начала достаточно Python 3, текстового редактора и терминала; Jupyter — необязательная удобная оболочка для исследований.
Что прочитать и посмотреть
- Python: venv — Creating virtual environments и команды активации для своей ОС. Бесплатно, английский.
- Pro Git — Главы «Основы Git»: создание репозитория, запись изменений, история, отмена изменений. Бесплатный текст на русском.
- Установить Python — Выберите установщик Python 3 для своей ОС. На Linux при отсутствии venv установите пакет python3-venv через менеджер пакетов своей системы. Бесплатно; справка на английском.
Что сделать
- Установите Python 3 по ссылкам из официального учебника. Откройте терминал в krug. На Windows проверьте py --version, на macOS/Linux — python3 --version.
- Создайте окружение: Windows — py -m venv .venv, macOS/Linux — python3 -m venv .venv. Запускайте код интерпретатором .venv/Scripts/python.exe (Windows) или .venv/bin/python (macOS/Linux). Это работает без активации.
- Установите pandas командой выбранного интерпретатора -m pip install pandas. Сохраните версии через -m pip freeze > requirements.txt. Создайте .gitignore с .venv/ и __pycache__/. Выполните git init, git add basics.py requirements.txt .gitignore, git commit -m "First calculation". При первом commit настройте имя и email локально по Pro Git.
Что сохранить
Рабочее окружение, requirements.txt, первый commit и инструкция запуска в обычном текстовом файле.
Как проверить себя
Запустите basics.py из нового окна терминала. Объясните, какой Python использован. Проверьте git status: окружение не попало в историю.
Разбор — откройте после своей попытки
Команда .venv/bin/python basics.py запускает файл на macOS/Linux; на Windows используйте .venv/Scripts/python.exe basics.py. Путь к программе и путь к файлу — разные аргументы. Если терминал не видит файл, сначала проверьте текущую папку; переустановка библиотек здесь не поможет.
Шаг 4. Получать строки и итоги с помощью SQL
Разберём на примере
SQL — язык запросов к таблицам. SELECT выбирает столбцы, WHERE оставляет строки по условию, GROUP BY объединяет строки для расчёта итогов. COUNT(*) считает строки; COUNT(column) пропускает NULL — неизвестные значения. Начинайте с маленького набора, в котором можете проверить каждый результат руками. Учебные запросы выполняются в SQLite Fiddle; PostgreSQL появится отдельно там, где нужны его особенности.
SELECT room_id, SUM(charged_cents-refund_cents) AS net_cents
FROM bookings WHERE status='completed'
GROUP BY room_id ORDER BY room_id;
Что прочитать и посмотреть
- SQLBolt — Уроки 1–12: SELECT, условия, JOIN, NULL и группировка. Выполните встроенные задания. Бесплатно, английский, без установки.
- SQLite Fiddle — Официальная SQL-песочница: вставьте учебный SQL и нажмите Run. Бесплатно, английский интерфейс; работаем только с вымышленными данными.
Что сделать
- Пройдите SQLBolt 1–5 и 10–12. Затем откройте SQLite Fiddle, вставьте содержимое bookings.sql из первого шага и выполните его один раз в пустой базе.
- Напишите SELECT для completed, затем итог net_cents по комнате. Используйте SUM(charged_cents-refund_cents).
- Добавьте условие day >= '2026-09-02'. Объясните, почему фильтр по строкам ставится до группировки. Сохраните запросы в results/queries.sql.
Что сохранить
Три SQL-запроса и таблица ожидаемых результатов.
Как проверить себя
Без фильтра итог A равен 6000, B — 7000 евроцентов. После фильтра даты A=2000, B=7000. Укажите, какие строки сформировали результат.
Разбор — откройте после своей попытки
Запрос ниже считает поступления после возвратов по комнатам. Cancelled с нулевыми суммами не меняет итог, но явный фильтр фиксирует бизнес-правило. Если повторно создать таблицу в той же базе, будет ошибка: начните новую сессию, не скрывайте ошибку.
Шаг 5. Соединять таблицы без потери и удвоения строк
Разберём на примере
Справочник хранит описание объекта один раз: код A соответствует комнате «Тихая». Первичный ключ уникально называет запись; внешний ключ связывает запись с другим объектом. JOIN сопоставляет строки по условию. Если одному бронированию соответствуют два платежа, после соединения оно появится дважды. Поэтому перед соединением назовите зерно обеих таблиц — что означает одна строка. LEFT JOIN сохраняет строки слева даже без пары; INNER JOIN оставляет только совпадения.
Что прочитать и посмотреть
- SQLBolt — Уроки 1–12: SELECT, условия, JOIN, NULL и группировка. Выполните встроенные задания. Бесплатно, английский, без установки.
- PostgreSQL: учебник — Разделы The SQL Language и Advanced Features: таблицы, соединения, внешние ключи, транзакции. Бесплатно, английский; команды PostgreSQL не переносите в SQLite без проверки.
Что сделать
- Пройдите SQLBolt 6–9. Создайте rooms(room_id TEXT PRIMARY KEY, name TEXT) и добавьте A/Тихая, B/Большая.
- Соедините bookings и rooms. Сверьте COUNT(*) и сумму net_cents до и после соединения.
- В отдельной CTE создайте платежи (1,1000),(1,1000),(2,2000). Соедините с bookings и объясните, почему сумма charged_cents теперь не является суммой всех бронирований. Сначала сгруппируйте платежи по booking_id.
Что сохранить
Запрос с соединением, проверками количества строк и пояснением отношения «один ко многим».
Как проверить себя
Со справочником остаются 6 строк и 13000 евроцентов net. В варианте с платежами бронирование 1 повторяется; проверка это обнаруживает.
Разбор — откройте после своей попытки
LEFT JOIN rooms USING(room_id) сохраняет шесть бронирований. Платежи имеют другое зерно: один перевод денег. Суммировать поля бронирования после такого соединения опасно. Сначала SELECT booking_id, SUM(amount) FROM payments GROUP BY booking_id; затем соединяйте этот итог.
Шаг 6. Использовать окна и проверять порядок событий
Разберём на примере
Оконная функция считает по группе, сохраняя исходные строки. ROW_NUMBER присваивает номер в заданном порядке; LAG возвращает значение предыдущей строки. В отличие от GROUP BY, можно одновременно видеть отдельное бронирование и место этого бронирования в истории пользователя. Если даты совпадают, добавьте booking_id в ORDER BY, иначе порядок не определён полностью. Дата бронирования и дата события оплаты могут быть разными: выберите нужную заранее.
Что прочитать и посмотреть
- SQLite: оконные функции — Примеры row_number(), PARTITION BY и сумм по окну. Бесплатная документация, английский.
CTE задаёт именованный промежуточный результат: WITH имя AS (запрос). Внешний SELECT затем читает его как таблицу. Так можно сначала вычислить номер строки, а затем отфильтровать его.
Что сделать
- Для каждого user_id пронумеруйте бронирования по day, booking_id. Выведите первые бронирования через CTE и внешний WHERE rn=1.
- Посчитайте накопленные net_cents по дням: сначала сгруппируйте по day, затем примените SUM(...) OVER (ORDER BY day ROWS UNBOUNDED PRECEDING).
- Добавьте копию даты с новым booking_id в рабочую базу. Убедитесь, что порядок внутри пользователя остаётся определённым; исходный файл не меняйте.
Что сохранить
Два оконных запроса и объяснение порядка вычислений.
Как проверить себя
Первые бронирования: 1,2,4,5. Дневные net: 4000,4000,5000; накопленные: 4000,8000,13000.
Разбор — откройте после своей попытки
Фильтрацию rn=1 выполняют снаружи CTE, после расчёта окна. Для u1 первой будет запись 1, следующей — отмена 3. Исключение cancelled до окна меняет вопрос на «первое завершённое бронирование»; явно укажите, какой вопрос решаете.
WITH numbered AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY user_id ORDER BY day, booking_id
) AS rn
FROM bookings
)
SELECT user_id, booking_id FROM numbered
WHERE rn = 1 ORDER BY user_id;
WITH daily AS (
SELECT day, SUM(charged_cents - refund_cents) AS net
FROM bookings GROUP BY day
)
SELECT day, net,
SUM(net) OVER (ORDER BY day ROWS UNBOUNDED PRECEDING) AS cumulative_net
FROM daily ORDER BY day;Шаг 7. Работать с файлами и командной строкой
Разберём на примере
Data Engineer делает поступление данных повторяемым. Скрипт должен знать вход, выход и условия ошибки. Абсолютный путь начинается от корня системы; относительный — от текущей папки. Для переносимого проекта используйте pathlib и аргументы командной строки. CSV хранит строки и столбцы, JSON может хранить вложенные объекты. Размер файла, кодировка и разделитель входят в договор о поставке, иначе две внешне похожие выгрузки могут читаться по-разному.
Что прочитать и посмотреть
- Учебник Python — Разделы An Informal Introduction, More Control Flow Tools, Data Structures и Errors and Exceptions. Бесплатно, английский; это справочник после первых упражнений, а не единственное объяснение с нуля.
- Python: JSON — load, dump и соответствие типов JSON/Python. Бесплатная документация, английский.
Что сделать
- В терминале перейдите в krug: команда cd. Проверьте содержимое через dir на Windows или ls на macOS/Linux. Запустите basics.py из этой папки выбранным интерпретатором.
- Напишите read_file.py с argparse: входной путь обязателен. Через csv.DictReader прочитайте raw/bookings.csv и преобразуйте числовые поля int. Сохраните JSON в results.
- Запустите из другой папки, передав корректный путь. Затем передайте отсутствующий файл и испорченный текст вместо суммы. Сохраните понятные сообщения об ошибках.
Что сохранить
Скрипт преобразования CSV → JSON и инструкция с двумя примерами запуска.
Как проверить себя
Шесть входных строк дают шесть объектов; суммы остались числами, идентификаторы — строками.
Разбор — откройте после своей попытки
csv.DictReader сам не превращает "2000" в число. Преобразование должно быть явным. Ошибка пути означает, что файл не найден по конкретному адресу; не нужно создавать пустую таблицу и объявлять загрузку успешной.
Шаг 8. Получить данные по HTTP и описать контракт
Разберём на примере
Источник может отдавать данные через API. Инженеру нужно знать адрес, параметры, формат ответа, ограничения размера и способ получить следующую страницу. Код 200 ещё не гарантирует, что тело соответствует ожидаемой схеме. Таймаут ограничивает ожидание ответа. Повтор временного сбоя может быть полезен; неверный формат повтором обычно не исправляется. Для начала используем локальный сервер, чтобы упражнение не зависело от регистрации и платного API.
Что прочитать и посмотреть
- Python: HTTP-клиент — urlopen, timeout и чтение ответа. Бесплатно, английский; в упражнении обращаемся к своему локальному серверу.
- MDN: клиент и сервер — Запрос, ответ, сервер и база данных. Бесплатно, английский.
- Python: JSON — load, dump и соответствие типов JSON/Python. Бесплатная документация, английский.
Что сделать
- Сохраните два файла page1.json и page2.json: items с разными учебными booking_id, next="page2.json" у первого и next=null у второго. Создайте их в отдельной папке только с учебными файлами.
- Запустите из неё python3 -m http.server 8765 --bind 127.0.0.1 либо py -m http.server 8765 --bind 127.0.0.1. В другом терминале прочитайте http://127.0.0.1:8765/page1.json через urlopen с timeout=5.
- Соберите обе страницы, проверяя items и next. Добавьте обнаружение повторяющейся ссылки next и ошибку отсутствующей страницы. Остановите свой сервер Ctrl+C.
Что сохранить
Локальный источник, клиент пагинации и протокол ошибок.
Как проверить себя
Каждый booking_id обработан один раз; циклический next не создаёт бесконечный запрос.
Разбор — откройте после своей попытки
Пагинация — выдача результата частями. Если API меняет данные между страницами, возможны пропуски и повторы; в реальном контракте уточняют стабильность снимка или курсора. Пример на двух файлах проверяет клиентскую логику, а не все гарантии внешнего API.
Шаг 9. Проверить данные до загрузки
Разберём на примере
Контракт данных задаёт имена полей, типы, ключи и смысл значений. Проверки качества должны отличать отсутствие суммы от нуля, дубль от новой версии и неизвестную комнату от пустой строки. Решение «отклонить весь пакет» или «пропустить плохие строки» меняет полноту отчёта. В первом проекте выберем остановку всего пакета при нарушении контракта, чтобы не публиковать неполный итог как полный.
Что прочитать и посмотреть
- dbt: проверки данных — not_null, unique, accepted_values и relationships. Бесплатная документация, английский; упражнения можно сначала выполнить SQL-запросами без облачной платформы.
- Python: unittest — Basic example, TestCase и assertRaises. Бесплатно, английский; дополнительная библиотека не нужна.
Что сделать
- Напишите validate(row): обязательны booking_id, room_id, суммы; status допускает completed/cancelled. Проверьте charged>=0 и 0<=refund<=charged.
- Создайте пять плохих пакетов: пропуск столбца, дубликат ключа, неизвестный статус, возврат больше оплаты и неизвестная комната C при справочнике A/B.
- Для каждого напишите unittest с ожидаемой ошибкой. В сообщении укажите правило и идентификатор строки, избегая полного дампа входа.
Что сохранить
Валидатор, пять тестов и выбранная политика отклонения пакета.
Как проверить себя
Плохой пакет не считается успешным, а предыдущий проверенный результат остаётся доступен.
Разбор — откройте после своей попытки
Проверка unique в пакете и уникальный ключ в хранилище решают разные задачи. Повтор всей вчерашней выгрузки не обязательно ошибка источника: загрузчик должен уметь распознать уже известные записи. Эту задачу решим через ключ и версию.
Шаг 10. Загрузить таблицу в SQLite из Python
Разберём на примере
SQLite — локальная база в одном файле, удобная для изучения загрузки без сервера. Модуль sqlite3 входит в Python. Параметризованный запрос передаёт значения отдельно от SQL, поэтому кавычка в строке не меняет структуру команды. Транзакция позволяет сохранить пакет целиком. Схему создают явно: типы, ключи и ограничения — часть договора. SQLite не воспроизводит все возможности серверного хранилища, но позволяет проверить логику.
Что прочитать и посмотреть
- Python: sqlite3 — Tutorial, placeholders и транзакции. Бесплатная документация, английский; модуль входит в стандартную библиотеку Python.
- Python: unittest — Basic example, TestCase и assertRaises. Бесплатно, английский; дополнительная библиотека не нужна.
Что сделать
- Создайте work/warehouse.sqlite и таблицу bookings с ключом booking_id. Выполните параметризованный INSERT через executemany, используя ? вместо склейки строк.
- Оберните пакет в транзакцию через with db. После загрузки проверьте COUNT(*) и SUM(charged_cents-refund_cents).
- В отдельной тестовой базе вставьте строку, затем намеренно вызовите исключение до завершения with db. Снова откройте файл и убедитесь, что строка не сохранилась.
Что сохранить
Загрузчик, SQL-сверка и тест отката.
Как проверить себя
После чистой загрузки 6 строк и 13000 евроцентов; при исключении пакет не фиксируется частично.
Разбор — откройте после своей попытки
Перед тестом отката создайте схему и завершите её подготовку отдельно. Затем проверяйте транзакцию изменения данных. Контекст with db фиксирует успешные изменения или откатывает исключение; само соединение после работы закройте явно.
Шаг 11. Разделить слои и построить витрину
Разберём на примере
Хранилище помогает нескольким потребителям получать согласованные данные. В учебном проекте raw хранит исходный файл, staging — проверенные строки, mart — таблицу для определённого вопроса. ETL означает преобразование до загрузки целевого результата, ELT — загрузку перед преобразованием внутри хранилища. В обоих случаях нужны проверки. Витрина по комнате и дню имеет другое зерно, чем исходные бронирования.
Что прочитать и посмотреть
- Power BI: схема «звезда» — Fact tables, Dimension tables и отношения: отделите измерения от фактов. Бесплатная документация, английский.
- PostgreSQL: учебник — Разделы The SQL Language и Advanced Features: таблицы, соединения, внешние ключи, транзакции. Бесплатно, английский; команды PostgreSQL не переносите в SQLite без проверки.
Что сделать
- Нарисуйте движение файла в staging и затем в mart_room_day. Подпишите зерно, ключ, владельца и проверку каждого слоя.
- Создайте SQL-витрину с day, room_id, bookings_count, completed_count и net_cents. Суммы не называйте прибылью.
- Проверьте, что сумма витрины равна источнику. Добавьте справочник комнаты и убедитесь, что соединение не умножает строки.
Что сохранить
Схема слоёв, запрос витрины и сверка итогов.
Как проверить себя
Ключ (day,room_id) уникален. Итог net равен 13000, completed_count в сумме равен 5.
Разбор — откройте после своей попытки
Считать COUNT(*) после группировки — значит считать группы, а не исходные бронирования. Для общего количества суммируйте bookings_count. Слой raw сохраняет исходное доказательство загрузки, поэтому исправления выполняются в следующих слоях.
Шаг 12. Сделать загрузку повторяемой и учитывать версии
Разберём на примере
Идемпотентная загрузка повторного пакета оставляет те же данные. Ключ находит запись, версия помогает отличить новое состояние от старого. Добавим updated_at — время изменения записи у источника, в UTC и едином формате. Оно отличается от дня бронирования. Учебный загрузчик принимает полные версии строк и обновляет только более новую; одинаковая версия с разным содержимым считается конфликтом, который нельзя разрешить произвольно.
CSV с учебными версиями и загрузчик Python. Это полные учебные версии, а не реальные отметки времени исходного сервиса.
Что прочитать и посмотреть
- Python: sqlite3 — Tutorial, placeholders и транзакции. Бесплатная документация, английский; модуль входит в стандартную библиотеку Python.
- Python: unittest — Basic example, TestCase и assertRaises. Бесплатно, английский; дополнительная библиотека не нужна.
Что сделать
- Скачайте bookings_versions.csv и pipeline.py ниже. Прочитайте validate и load, затем запустите своим интерпретатором pipeline.py raw/bookings_versions.csv work/versions.sqlite. Используйте эту отдельную базу: warehouse из предыдущего шага имеет другую схему.
- Повторите пакет и сравните итог. Создайте обновление booking_id=2: refund_cents=1500, updated_at=2026-09-06T00:00:00Z. Остальные поля сохраните.
- Примените обновление, затем снова старый пакет. Проверьте, что возврат не откатился. Создайте конфликт той же версии с другой суммой и убедитесь, что пакет отклонён.
Что сохранить
Повторяемая загрузка, обновлённая запись и тест старой версии.
Как проверить себя
После первого и повторного запуска 6 строк и 13000. После нового возврата 12500; старый пакет оставляет 12500.
Разбор — откройте после своей попытки
ON CONFLICT по ключу не решает проблему версий сам по себе: без условия старый пакет перезапишет новое значение. Время версии должно быть достаточно точным и надёжным по контракту источника; в реальной системе часто нужен порядковый номер изменения.
Шаг 13. Организовать инкремент и поздние изменения
Разберём на примере
Полная загрузка перечитывает всё, инкрементальная — только изменения. Watermark — сохранённая граница обработанных изменений, например пара (updated_at, id). Запрос только «новее вчера» может пропустить позднюю запись или записи с одинаковым временем. Выборка с перекрытием и идемпотентная загрузка позволяют безопасно перечитать часть истории, но гарантии зависят от источника. Удаление нужно передавать отдельно: отсутствие строки в инкременте не означает удаление.
Что прочитать и посмотреть
- Python: sqlite3 — Tutorial, placeholders и транзакции. Бесплатная документация, английский; модуль входит в стандартную библиотеку Python.
- PostgreSQL: учебник — Разделы The SQL Language и Advanced Features: таблицы, соединения, внешние ключи, транзакции. Бесплатно, английский; команды PostgreSQL не переносите в SQLite без проверки.
Что сделать
- Составьте журнал из пяти изменений: две записи с одним updated_at, более поздний возврат и явное удаление с признаком is_deleted.
- На бумаге проверьте границу только по времени и границу по паре время/ключ. Укажите условия, при которых источник гарантирует полноту такой выборки.
- Опишите перекрытие окна, сверку полного снимка и обработку удалений. Продвигайте watermark только вместе с успешной фиксацией пакета.
Что сохранить
Алгоритм инкремента и таблица поздних событий.
Как проверить себя
Сбой не сдвигает границу дальше необработанных данных. Удаление не выводится из неполного списка.
Разбор — откройте после своей попытки
Пара время/ключ помогает пройти одинаковое время в устойчивом порядке, но не спасает от задним числом добавленного изменения до границы. Для этого нужны гарантированный журнал изменений, перекрытие с известной задержкой или периодическая полная сверка.
Шаг 14. Описать зависимости, расписание и повторный запуск
Разберём на примере
Оркестратор запускает задачи по зависимостям и отслеживает результат. DAG — граф без циклов: получить → проверить → загрузить → построить витрину → сверить. Расписание отвечает, когда попытаться запустить, но не гарантирует готовность источника. Backfill — пересчёт прошлых периодов. Задача должна явно получать период, чтобы сегодняшний запуск мог обработать прошлую дату без подмены системных часов.
Что прочитать и посмотреть
- Apache Airflow: учебники — Первый DAG: зависимости задач, расписание и повторный запуск. Бесплатно, английский; сверяйте пример с установленной версией Airflow.
- Python: unittest — Basic example, TestCase и assertRaises. Бесплатно, английский; дополнительная библиотека не нужна.
Что сделать
- Сначала напишите локальный run.py, который вызывает этапы последовательно и прекращает работу после ошибки. Передавайте дату аргументом, не зашивайте today во все функции.
- Нарисуйте DAG и для каждого узла задайте вход, выход, условие успеха и допустимый повтор. Сымитируйте отсутствие источника и неверный столбец.
- Изучите первый пример Airflow. Сопоставьте его task и зависимости с вашей схемой. Сохраните проект переноса. Лаборатория с запуском Airflow находится в шаге 20.
Что сохранить
Рабочий локальный запуск и схема будущего расписания.
Как проверить себя
Витрина не запускается после проваленной проверки. Повтор после сбоя не удваивает данные.
Разбор — откройте после своей попытки
Сетевой таймаут допускает ограниченный повтор, а неизвестная схема обычно требует исправления контракта. Безусловный retry не является универсальной обработкой ошибок. Завершённый локальный запуск не следует указывать как опыт эксплуатации Airflow.
Шаг 15. Добавить наблюдение и инструкцию восстановления
Разберём на примере
Успех процесса не равен свежести данных: скрипт может завершиться без ошибки с пустым вчерашним файлом. Контроль загрузки должен видеть период, число строк, версию схемы, контрольную сумму и время последнего успешного результата. SLO — согласованный измеримый ориентир качества сервиса, например готовность проверенной дневной витрины к 09:00. Нужно определить часовой пояс, календарь рабочих дней и способ заметить нарушение.
Что прочитать и посмотреть
- Python: logging — Basic Logging Tutorial и базовая настройка сообщений. Бесплатно, английский.
- Python: unittest — Basic example, TestCase и assertRaises. Бесплатно, английский; дополнительная библиотека не нужна.
Что сделать
- Добавьте logging с run_id, периодом, этапом, числом входных и выходных строк и ошибкой. Секреты и полный исходник в лог не пишите.
- Смоделируйте пустую выгрузку, поздний файл и падение после загрузки до витрины. Для каждого задайте критерий обнаружения.
- Напишите инструкцию: как найти последний успех, проверить источник, исправить причину, повторить период и сверить итог. Сохраните старый корректный результат до успешной замены.
Что сохранить
Журнал трёх отказов и инструкция восстановления.
Как проверить себя
По одному run_id можно понять, что обработано и какой этап требует повтора.
Разбор — откройте после своей попытки
Нулевое число строк может быть нормой в день без работы, поэтому правило зависит от календаря и источника. В учебном пакете ожидается шесть строк; в рабочем процессе нельзя без объяснения применять это число ко всем датам.
Шаг 16. Сравнить CSV и Parquet на измерениях
Разберём на примере
Parquet хранит таблицу по столбцам и сохраняет типы; это помогает некоторым аналитическим чтениям выбирать только нужные поля. CSV проще открыть глазами, но его типы надо восстанавливать. Формат сам по себе не гарантирует ускорение: влияют размер, сжатие, число файлов и способ чтения. Маленькие файлы могут создавать лишние расходы. Сначала сравнивайте корректность, затем время и размер.
Что прочитать и посмотреть
- Apache Arrow: Parquet — Чтение и запись таблицы, выбор столбцов и сжатие. Бесплатно, английский; библиотека pyarrow устанавливается только для этого упражнения.
- pandas: вводные уроки — Read and write tabular data, Select a subset, Calculate summary statistics, Combine data. Бесплатно, английский.
Что сделать
- Установите pyarrow в своё окружение командой его интерпретатора -m pip install pyarrow и обновите requirements.txt. Прочитайте в pandas материал Read and write tabular data. Выполните import pandas as pd; df = pd.read_csv("raw/bookings.csv"). Затем df.to_csv("results/bookings.csv", index=False) и df.to_parquet("results/bookings.parquet", index=False).
- Прочитайте оба файла с согласованными типами и сравните ключи и суммы. В Parquet отдельно прочитайте только room_id и суммы.
- Создайте 100000 учебных строк с уникальными booking_id повторением значений других полей. Трижды измерьте запись и чтение, зафиксируйте размер и условия. Не переносите результат на любой рабочий объём.
Что сохранить
Два формата и протокол измерений.
Как проверить себя
Контрольные суммы совпадают; ускорение не получено потерей строк или точности сумм.
Разбор — откройте после своей попытки
На шести строках накладные расходы могут быть больше выигрыша. Учебное повторение одних и тех же значений особенно хорошо сжимается, поэтому его размер не является прогнозом для разнообразных данных.
Шаг 17. Создать контракт витрины и SQL-тесты
Разберём на примере
Потребитель витрины рассчитывает на стабильное зерно, типы и смысл показателей. Аналитическая инженерия соединяет SQL-преобразования с версиями, тестами и документацией. В dbt многие проверки выражаются как запрос, возвращающий нарушающие правило строки. Этот принцип можно сначала реализовать непосредственно в SQLite: пустой результат означает, что конкретное нарушение не найдено, а не что данные идеальны.
Что прочитать и посмотреть
- dbt: проверки данных — not_null, unique, accepted_values и relationships. Бесплатная документация, английский; упражнения можно сначала выполнить SQL-запросами без облачной платформы.
- Pro Git — Главы «Основы Git»: создание репозитория, запись изменений, история, отмена изменений. Бесплатный текст на русском.
Что сделать
- Напишите запросы на NULL ключа, повтор (day,room_id), неизвестную комнату и несовпадение общего net с источником.
- Соберите команду проверки всех запросов: при найденной строке она заканчивается ошибкой. Поместите SQL и описание зерна в Git.
- Измените метрику: вместо net нужен charged отдельно от refund. Выпустите новую версию витрины с понятными именами и обновите потребительский пример.
Что сохранить
SQL-тесты, словарь витрины и журнал изменения.
Как проверить себя
Намеренно испорченная витрина обнаруживается. Старая формула не меняет смысл под тем же названием незаметно.
Разбор — откройте после своей попытки
Проверка unique и not_null не обнаруживает неправильную бизнес-формулу. Сверяйте формулу с независимым расчётом по источнику. Практическую работу в dbt отметьте только после отдельного запуска инструмента, а не после чтения названий тестов.
Шаг 18. Собрать самостоятельный конвейер
Разберём на примере
Итоговый источник — вымышленный прокат игр: выдачи, строки предметов и платежи. Один платёж может быть исправлен новой версией, возврат может прийти позднее. Вы должны передать готовую обработку от входа до проверенной витрины. Сначала согласуйте контракт и ожидаемый итог, затем напишите код. Учебный проект можно выполнить целиком на Python и SQLite без облачного аккаунта.
Что прочитать и посмотреть
- Python: sqlite3 — Tutorial, placeholders и транзакции. Бесплатная документация, английский; модуль входит в стандартную библиотеку Python.
- Python: unittest — Basic example, TestCase и assertRaises. Бесплатно, английский; дополнительная библиотека не нужна.
- Pro Git — Главы «Основы Git»: создание репозитория, запись изменений, история, отмена изменений. Бесплатный текст на русском.
Что сделать
- Подготовьте минимум два дневных пакета: 12 выдач, 20 предметов и платежи, включая дубль, новый возврат и старую версию после новой. Получите контрольный итог от проверяющего или посчитайте отдельно вручную.
- Реализуйте загрузку, проверки, витрину по дню денежных движений, журнал и запуск с аргументом периода. Сохраните версии зависимостей и инструкцию.
- Измените условие: источник присылает удаление ошибочного платежа. Обновите контракт и тесты, выполните backfill. Передайте запуск другому человеку в новой папке.
Что сохранить
Конвейер, отрицательные тесты, контрольные суммы и инструкция восстановления.
Как проверить себя
Повтор не меняет итог, поздний возврат учитывается, удаление обработано по договорённому признаку, плохой пакет не заменяет хороший результат.
Разбор — откройте после своей попытки
Не соединяйте платежи с каждым предметом и затем не суммируйте оплату: сумма умножится. Агрегируйте данные с разным зерном до согласованного уровня или храните отдельные факты.
Шаг 19. Проверить готовность и выбрать вакансии
Разберём на примере
Название «Data Engineer» не задаёт одинаковые обязанности во всех компаниях. Сравнивайте задачи, уровень самостоятельности, язык команды и условия работы. Европа — основной ориентир этой программы; вакансии РФ помогают увидеть совпадения и отличия. Старшие вакансии показывают дальнейшее развитие, но не превращают весь их список в обязательный входной порог. Диплом, местный язык и опыт могут быть отдельными условиями работодателя. Учебный проект не заменяет коммерческий опыт.
Что прочитать и посмотреть
- Pro Git — Главы «Основы Git»: создание репозитория, запись изменений, история, отмена изменений. Бесплатный текст на русском.
Что сделать
- Соберите пять свежих европейских и три российских вакансии. Запишите дату, страну, реальный уровень по обязанностям, обязательные требования и пожелания в разные столбцы. Обновляйте ссылки перед откликом.
- Для каждого требования приложите своё доказательство: загрузчик, SQL-модель, тесты повторов и версий, журнал отказов и инструкция восстановления. Отметьте «делал самостоятельно», «с подсказкой» или «пока не делал». Выберите три пробела и задания для их закрытия.
- Попросите знакомого провести 20-минутное собеседование по вашему проекту. Объясните задачу на русском и кратко на английском: problem, method, result, limitation. Выполните новое небольшое задание без готового решения и запишите, где потребовалась помощь.
Что сохранить
Матрица вакансий, портфолио из собственных файлов и план закрытия трёх пробелов.
Как проверить себя
Другой человек может открыть проект, повторить ключевой результат и задать вопрос о неудачном варианте. В резюме учебные проекты обозначены как учебные.
Разбор — откройте после своей попытки
«Знаю SQL» не является доказательством. Подойдёт ссылка на ваш файл запроса, входные данные, ожидаемый результат и описание ошибки, которую запрос выявляет. Если проверяющего пока нет, отметьте внешнюю проверку как незавершённую; не заменяйте её галочкой.
Шаг 20. Перенести проект на серверную базу и оркестратор
Разберём на примере
Следующая практика добавляет эксплуатационные условия: PostgreSQL, контейнеры и Airflow. Контейнер запускает приложение с описанным окружением; volume сохраняет данные отдельно от заменяемого контейнера. Compose описывает несколько сервисов. Изучайте их по одному: сначала собственная тестовая база, затем загрузчик, потом расписание. Команды и примеры сверяйте с установленной версией; готовый Compose из интернета требует чтения до запуска.
Что прочитать и посмотреть
- Docker: начало — What is a container, images, volumes и Compose. Бесплатная документация, английский; проверьте условия Docker Desktop для своего использования.
- PostgreSQL: учебник — Разделы The SQL Language и Advanced Features: таблицы, соединения, внешние ключи, транзакции. Бесплатно, английский; команды PostgreSQL не переносите в SQLite без проверки.
- Apache Airflow: учебники — Первый DAG: зависимости задач, расписание и повторный запуск. Бесплатно, английский; сверяйте пример с установленной версией Airflow.
Что сделать
- По официальному Docker Get Started разберите image, container, port и volume. Создайте отдельный учебный проект PostgreSQL с портом, доступным только через 127.0.0.1, и собственным volume.
- Перенесите загрузчик, учитывая синтаксис параметров драйвера и транзакции PostgreSQL. Повторите проверки дублей, версий и отката.
- По официальному quick start установленной версии Airflow создайте DAG для вашего периода. Проверьте retry и backfill на двух днях. Запишите фактический расход памяти и способ остановить только свои контейнеры.
Что сохранить
Запускаемая серверная версия и проверенный DAG.
Как проверить себя
Данные переживают перезапуск своего контейнера. Пароли не записаны в Git, реальные системы не используются.
Разбор — откройте после своей попытки
Установка нескольких инструментов не доказывает переносимость. Доказательство — те же контрольные итоги и ожидаемые отказы после переноса. Если компьютер не поддерживает такую лабораторию, оставьте практику шага открытой, а не заявляйте владение Airflow по схеме.
Шаг 21. Попробовать распределённую и потоковую обработку
Разберём на примере
Spark распределяет вычисления, но на маленьком наборе может проигрывать простому SQL по накладным расходам. Kafka хранит поток записей в разделах; порядок гарантируется в рамках раздела, а не автоматически между всеми событиями. Event time — время события, processing time — время обработки. Запоздавшее событие требует политики пересчёта или допустимой задержки. Начните локально, не оплачивая кластер.
Что прочитать и посмотреть
- PySpark: начало — DataFrame, преобразования и выполнение вычислений. Бесплатно, английский; распределённый кластер в платном облаке не нужен.
- Apache Kafka: документация — Introduction и Quickstart: topic, partition, producer, consumer. Выберите документацию своей версии. Бесплатно, английский.
Что сделать
- По PySpark Getting Started установите совместимые Python и Java, затем выполните группировку учебного файла в local-режиме. Сверьте результат с SQLite.
- По Kafka Quickstart своей версии создайте отдельный локальный topic, отправьте три учебных события и прочитайте их. Добавьте повтор одного event_id.
- Опишите ключ разбиения по booking_id и обработку позднего возврата. Измерьте время запуска и обработки отдельно; не обещайте выигрыш на шести строках.
Что сохранить
Две маленькие лаборатории и таблица гарантий обработки.
Как проверить себя
Порядок по одному ключу не выдан за глобальный. Суммы совпадают, дубль распознаётся.
Разбор — откройте после своей попытки
Spark и Kafka решают разные части задачи и не обязаны появляться вместе в каждом проекте. Выбор основывается на объёме, задержке и требованиях восстановления. Локальная лаборатория не является опытом сопровождения распределённого кластера.
Шаг 22. Спроектировать облачный вариант и план роста
Разберём на примере
Облачный проект требует выбора хранения, вычислений, доступа и контроля расходов. Начать можно с проекта решения без платного аккаунта: оцените объём входа, срок хранения, число чтений и задержку. Затем сравните объектное хранилище, аналитическую базу и обработку по расписанию. Тарифы и условия бесплатного уровня меняются; их проверяют непосредственно перед практикой. Следующая специализация может быть batch, streaming или платформа данных.
Что прочитать и посмотреть
- Power BI: схема «звезда» — Fact tables, Dimension tables и отношения: отделите измерения от фактов. Бесплатная документация, английский.
- Docker: начало — What is a container, images, volumes и Compose. Бесплатная документация, английский; проверьте условия Docker Desktop для своего использования.
- dbt: проверки данных — not_null, unique, accepted_values и relationships. Бесплатная документация, английский; упражнения можно сначала выполнить SQL-запросами без облачной платформы.
Что сделать
- Составьте схему облачного аналога вашего локального проекта: источник, raw, обработка, витрина, права и наблюдение.
- Для 1 ГБ входа в сутки и 30 дней хранения посчитайте исходный объём без сжатия и копий. Добавьте резервную копию и объясните, какие расходы ещё не посчитаны.
- Выберите пять вакансий направления, два пробела и два проекта с внешней проверкой. Для кода от AI проверьте повторный запуск, старую версию и частичный сбой до любого рабочего применения.
Что сохранить
Проект решения, перечень затрат и план специализации.
Как проверить себя
Учебный расчёт объёма не назван бюджетом без текущих тарифов, вычислений и передачи данных.
Разбор — откройте после своей попытки
За 30 дней получается 30 ГБ входных данных; одна полная дополнительная копия доводит хранимый объём до 60 ГБ без сжатия и промежуточных слоёв. Это модель объёма, а не стоимость. Начать специализацию можно локально, оставив облачную эксплуатацию отдельной проверяемой практикой.