Часть 4. Окружение: Qwen Code, dbt, DuckDB
Окружение должно быть локальным, воспроизводимым и достаточно маленьким, чтобы студент видел SDD-цикл, а не боролся с инфраструктурой. Поэтому в учебном треке используются Python, DuckDB, dbt-core и dbt-duckdb.
Минимальные требования
- Python 3.11+;
venv;- shell с
bash; - Qwen Code CLI или совместимый агент-инструмент;
- доступ к локальному репозиторию.
Проверка:
python3 --version
python3 -m venv /tmp/sdd-data-check
. /tmp/sdd-data-check/bin/activate
pip --version
Установка примера
cd book3/examples/bank-lakehouse
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
bash smoke_all.sh
Полный smoke-прогон должен сгенерировать raw/seeds, выполнить dbt parse и dbt build. Если dbt не установлен, запасной режим проверит только структуру. Это частичная проверка, а не доказательство готовности учебника.
Почему DuckDB
DuckDB позволяет показать SQL, типы, агрегаты, dbt-тесты и локальное хранилище без внешнего сервиса. Это делает ошибки дешевле. Если revoked_at пустой и приведение типа ломается, студент видит проблему в контракте source/staging, а не в настройках
кластера.
DuckDB не заменяет боевой контур. Он заменяет первый учебный контур. После того как локально понятны grain, политика PII и контракты, ту же схему можно перенести на Trino, Spark, Databricks или Snowflake.
Настройка агента
В примере есть AGENTS.md и .qwen/commands/sdd/. Перед любым изменением моделей агент должен прочитать:
AGENTS.md;specs/mission.md;specs/tech-stack.md;- нужные ODCS/ODPS;
- нужная спецификация модели;
- проверочные факты.
Не начинайте с «почини dbt». Начинайте с «сравни ошибку с контрактом и покажи, какой факт нарушен».
Разбор для читателя
Локальное окружение в этой книге намеренно скромное. Это не попытка сделать вид, что боевой контур устроен просто. Наоборот: маленький стек нужен, чтобы отделить учебную ошибку от инфраструктурного шума. Когда dbt build падает на пустой дате, читатель должен видеть проблему в staging и контракте, а не разбираться с кластером, секретами, правами, каталогом и сетевыми политиками.
DuckDB полезен именно как лаборатория. Он достаточно похож на аналитический движок, чтобы показать типы, агрегаты, materialization и тесты. При этом он
достаточно близок, чтобы студент мог удалить базу, пересобрать данные и снова получить тот же результат. Такая воспроизводимость важнее ощущения «настоящей» платформы. Если первый учебный контур не воспроизводится локально, перенос на Iceberg или Spark только добавит новые причины для случайных расхождений.
Отдельный venv — тоже часть дисциплины. Он фиксирует границы примера: вот версии инструментов, вот команда установки, вот команда проверки. Когда пины обновляются, это должно подтверждаться smoke-прогоном, а не доверием к названию «latest». Для учебника это особенно важно: читатель копирует команды, и если они ломаются, он перестаёт доверять не только окружению, но и процессу.
Наконец, окружение задаёт правильное отношение к агенту. Агент не должен получать команду «почини всё», когда dbt не запускается. Сначала нужно понять, какая граница нарушена: зависимость не установлена, raw-данные отсутствуют, staging неверно трактует пустое значение, контракт не совпадает с моделью. Чем меньше окружение, тем проще научиться этой диагностике.
Практика
Запустите smoke_all.sh в двух режимах: без активированного venv и после
установки зависимостей. Запишите, какой режим является частичным, какой полным, и какие строки вывода доказывают успешный dbt build.
Минимальный выход
После главы у вас должно быть:
- локально установленное окружение;
- успешный или честно зафиксированный
smoke_all.sh; - понимание, какой режим проверки был полным, а какой частичным;
- заметка о том, где лежат specs, models, tests и артефакты ревьюера.
Типичная ошибка
Игнорировать запасной smoke-прогон. Сообщение «проверка структуры и генерации данных пройдена» не означает, что dbt-модели корректны. Это только проверка, что пример можно открыть и сгенерировать raw-файлы.
Контрольные вопросы
- Почему локальный DuckDB полезнее боевого кластера на первом проходе?
- Чем частичный smoke отличается от полного?
- Какие файлы агент должен прочитать перед изменением mart?