Часть 11. Проверка данных: validation.md
В SDD проверка — это не фраза «данные корректны». Это набор фактов. В дата-проекте факт должен связывать спецификацию, SQL и доказательство. Если факт нельзя выполнить командой, SQL-запросом или ручным шагом ревьюера, он пока не готов.
Пример проверочных фактов
### F1 — Customer 360 grain
- Команда: `dbt test --profiles-dir . --select mart_customer_360`
- Ожидание: `customer_id` unique и not_null.
- Статус: принято.
### F2 — PII не попало в mart
- Команда: `dbt test --profiles-dir . --select assert_customer_360_no_direct_pii`
- Ожидание: тест возвращает 0 строк.
- Статус: принято.
Автоматические и ручные факты
Автоматические факты запускаются командой. Ручные факты требуют чтения изменения или подтверждения бизнеса. Оба типа нужны. dbt не знает, что «активный клиент» определён правильно, если это не записано в спецификации.
Хороший ручной факт:
Ревьюер подтвердил, что добавление `product_code` изменило бы grain и не входит
в эту фазу.
Плохой ручной факт:
Выглядит нормально.
Где хранить validation
В учебном примере заметки о проверке лежат в specs/validation/. Это не
обязательно единственное место, но правило такое: validation.md должен быть версионируемым и читаемым после /clear. Если факт живёт только в чате, он не может быть доказательством релиза.
Qwen-запрос
Создай черновик validation.md для mart_customer_360.
Используй specs/models/mart_customer_360.md, ODCS, ODPS и models/schema.yml.
Не меняй dbt-модели.
Минимальный выход
Минимальный validation.md для витрины должен содержать:
- один факт про grain;
- один факт про PII;
- один факт про обязательные поля контракта;
- один факт про lineage или список входных моделей;
- один ручной факт: изменение не меняет поля контракта без утверждения.
Если факт нельзя проверить, перепишите его как команду, SQL-запрос, dbt-тест или шаг ревьюера.
Разбор для читателя
validation.md — место, где учебник намеренно становится строгим. Пока факт не имеет команды, SQL-запроса или ручного шага ревьюера, он остаётся пожеланием. Фраза «данные корректны» ничего не защищает: агент может считать корректностью отсутствие ошибок выполнения, аналитик — отсутствие пустых значений, владелец продукта — сохранение grain. Проверочный факт убирает эту двусмысленность.
Не все факты нужно автоматизировать. В данных есть решения, которые требуют чтения изменения и понимания контракта. Например, dbt может доказать, что customer_id уникален, но он не решит, допустимо ли добавление product_code в Customer 360. Такой факт лучше оставить ручным и явно назначить ревьюеру. Ручной не значит слабый; слабым он становится только тогда, когда не указано, что именно читать и какой вывод сделать.
Хорошая заметка о проверке связывает несколько слоёв: спецификацию модели, ODCS, models/schema.yml, singular-тесты и отчёт ревьюера. Если один из слоёв изменился, validation.md должен показать, какие факты нужно пересмотреть. Это делает изменение данных похожим на инженерный процесс, а не на набор разрозненных SQL-патчей.
Читателю стоит привыкнуть писать validation.md до SQL. Это неудобно только в первый раз. Потом проверочные факты начинают помогать: они ограничивают размер решения, подсказывают, какие тесты нужны, и дают ревьюеру готовую рубрику. Если validation.md пишется после SQL, этот файл часто превращается в оправдание уже сделанного.
Практика
Возьмите один слабый пункт вроде «проверить качество данных» и перепишите его в
три формы: dbt-команда, SQL/singular-тест и ручной факт ревьюера.
Типичная ошибка
Писать «проверить качество данных». Это не факт. Факт звучит так: «customer_id уникален в mart_customer_360, команда `dbt test --select mart_customer_360` возвращает код выхода 0».
Контрольные вопросы
- Чем проверочный факт отличается от пожелания?
- Какие факты нельзя полностью автоматизировать?
- Почему ревьюер должен читать validation.md до изменения?