Проверки качества данных в аналитике: опыт внедрения
Проверки данных не спасают, если срабатывают на каждом допустимом отклонении или приходят после отчёта. Разбираем, как внедрять их поэтапно: от правил в SQL до реакции на сбой в production.

Если в отчёте внезапно обнулилась выручка, проверка «таблица обновилась» не поможет: данные могли приехать вовремя, но без части заказов. Чтобы находить такие сбои до публикации отчёта, проверки нужно привязать к смыслу метрик и разделить по критичности. Ниже — практический сценарий внедрения на связке dbt Core 1.9 и PostgreSQL 16; цифры качества и пороги команда определяет по своим данным, а не берёт из универсального шаблона.
Сначала определите, что именно может сломаться
Не начинайте с десятков тестов на каждую колонку. Сначала выпишите, какие ошибки повлияют на решение пользователя: пропавшие заказы, дубли в ключевой таблице, задержка загрузки, отрицательная сумма там, где её быть не должно. Для каждого риска зафиксируйте, какой набор данных проверяется, когда проверка должна сработать и кто получит сигнал.
Практичный первый охват — модели, на которых держатся ежедневные отчёты, финансовые расчёты и ключевые продуктовые метрики. Второстепенные таблицы подключайте позже. Так команда сначала защищает данные с высокой ценой ошибки, а не тратит время на формальные проверки полей, которыми никто не пользуется.
Четыре группы проверок
- Наличие и свежесть. Таблица не пуста, а время последней загрузки укладывается в ожидаемое окно. Учитывайте расписание и задержки источника: универсальный порог в несколько часов может быть неверным.
- Структура. Ключ не пустой и не повторяется там, где строка должна соответствовать одной сущности. Например, один заказ — одна запись в витрине заказов.
- Допустимые значения. Статус входит в согласованный перечень, сумма соответствует правилам предметной области. Отрицательная сумма может быть ошибкой, а может быть корректным возвратом — правило сначала сверяют с владельцем метрики.
- Согласованность. Связанные показатели не расходятся без объяснимой причины: например, идентификатор заказа в факте продаж должен находиться в таблице заказов.
Термин: тест на нарушение условия — запрос, который возвращает строки с проблемами. Если запрос вернул ноль строк, правило выполнено. В dbt такие проверки называются singular data tests; их SQL хранится отдельно от SQL-модели.
Выберите слой проверки, а не один универсальный инструмент
Проверки можно разместить в разных местах. Выбор зависит от того, где ошибка становится заметной и кто способен её исправить. Не стоит дублировать каждое условие во всех слоях: одинаковые тесты усложняют поддержку и могут выдавать несколько сигналов об одном сбое.
| Подход | Что проверяет лучше всего | Цена и ограничение |
|---|---|---|
| Ограничения PostgreSQL | Базовые правила записи: обязательность поля, уникальность, связи между таблицами | Защищают данные на уровне базы, но не заменяют проверки бизнес-правил между моделями и источниками |
| SQL-тесты в dbt | Правила аналитических моделей: ключи, диапазоны значений, связи и условия бизнеса | Нужны настройка запуска, владелец теста и понятная реакция на падение; сам тест не исправит источник |
| Проверки в отчёте или BI | Ошибки отображения и согласованность конкретного дашборда | Сбой обнаруживается поздно, а другая витрина может продолжить показывать некорректные данные |
Для критичных правил полезны два уровня: ограничение базы не допускает явно невозможную запись, а тест dbt проверяет уже собранную аналитическую модель. Проверка только в BI подходит как дополнительный контроль представления, но не как единственная защита конвейера.
Добавляйте тесты поэтапно
- Выберите одну модель и владельца. Возьмите таблицу, от которой зависит важный отчёт. Назначьте человека или команду, которые подтвердят смысл правил и разберут падение. Проверка без владельца быстро становится шумом.
- Опишите сбой наблюдаемым условием. Не «данные выглядят странно», а «в модели есть запись без идентификатора заказа». Условие должно быть проверяемым запросом и вести к понятному действию.
- Запустите тест на истории. Сначала выясните, сколько строк он находит в обычные дни. Если правило постоянно срабатывает на легитимные возвраты или поздние события, уточните определение, а не отключайте уведомления.
- Разделите блокирующие и предупреждающие проверки. Блокирующей делайте проверку, провал которой делает отчёт опасным для использования. Остальные сначала отправляйте в наблюдение, чтобы увидеть частоту сбоев и ложных тревог.
- Подключите сигнал и инструкцию. Уведомление должно содержать модель, название проверки, время запуска и ссылку на владельца или процедуру разбора. После исправления повторно запустите проверку и убедитесь, что затронутый отчёт обновился.
Каждый шаг можно считать завершённым только после проверки результата: правило действительно находит известную ошибку или проходит на допустимых данных, а сигнал доходит до ответственного. Не проверяйте тревожную цепочку на production, намеренно портя боевые таблицы: используйте тестовую среду или безопасный набор данных.
Пример теста для dbt
Для dbt Core 1.9 singular test — SQL-файл в каталоге тестов проекта. Следующий запрос проверяет, что у модели заказов нет пустого ключа. Модель fct_orders должна существовать в проекте.
-- tests/orders_have_order_id.sql
select order_id
from {{ ref('fct_orders') }}
where order_id is nullТест считается пройденным, когда запрос не возвращает строк. В отдельном файле можно проверить уникальность ключа:
-- tests/orders_have_unique_order_id.sql
select order_id
from {{ ref('fct_orders') }}
group by order_id
having count(*) > 1Перед тем как сделать такую проверку блокирующей, подтвердите, что модель действительно хранит одну строку на заказ. Если в ней намеренно несколько строк на заказ — например, по одной на позицию, — дубли ключа нормальны, и тест должен проверять другой идентификатор или другое зерно данных.
Хорошая проверка отвечает не только на вопрос «данные плохие?», но и на два следующих: насколько это опасно и кто должен действовать.
Что чаще всего ломается
- Проверка слишком строгая. Тест запрещает значения, которые возникают при возвратах, корректировках или поздних событиях. Сверьте правило с владельцем метрики и реальными историческими данными.
- Порог свежести игнорирует расписание. Задержка источника превращается в повторяющиеся тревоги. Учитывайте время запуска, выходные и известные задержки; порог пересматривайте вместе с командой источника.
- Проверка останавливает всю доставку данных. Это опасно, если тест некритичный или причина сбоя ещё неизвестна. Для каждого теста заранее решите, блокирует ли он публикацию, и кто может принять решение продолжить.
- Пересчёт истории выглядит как поломка. Backfill — повторная загрузка или пересчёт прошлых данных — способен резко изменить объём и распределение значений. Учитывайте это в проверках и сообщайте о плановых пересчётах.
- Сообщение не помогает найти причину. «Тест упал» мало что даёт. Добавьте контекст: какая модель проверялась, какие строки нарушили правило и к кому обращаться. Не помещайте в уведомление персональные данные без необходимости.
Когда какой подход выбирать
Если нужно запретить пустой обязательный столбец или повтор первичного ключа при записи, начинайте с ограничений PostgreSQL — при условии, что правило применимо на уровне базы и не мешает загрузке. Если проверяется смысл уже собранной витрины, например допустимые статусы или связь факта с измерением, используйте тест dbt. Если риск касается только расчёта или отображения конкретного дашборда, добавьте контроль в BI, но не рассчитывайте на него как на раннее обнаружение сбоя.
Сравнивайте не только число пройденных тестов. Отслеживайте, сколько времени проходит от сбоя до сигнала, сколько тревог оказываются ложными, сколько времени занимает разбор и какие ошибки дошли до пользователей. Если исходных измерений нет, соберите базовый уровень за несколько циклов загрузки: придумывать «нормальный» процент ошибок для всех проектов нельзя.
Что делать дальше
Возьмите одну критичную модель, зафиксируйте её зерно данных, ключ и ожидаемое расписание обновления. Добавьте сначала проверки на пустые и повторяющиеся ключи, затем — одно правило предметной области, подтверждённое владельцем показателя. После нескольких запусков решите, какие проверки блокируют публикацию, а какие пока только наблюдаются. Смежная задача — автоматическое исправление плохих записей; здесь мы разбирали обнаружение и реакцию, а не очистку данных.
Аналитик звонков: Разбор записи звонка по этапам сделки: где сорвалось, что упущено, три исправляемые рекомендации с цитатами.
Спросить за 90 ₽Источники: dbt documentation: Data tests, PostgreSQL 16 documentation: Constraints
Частые вопросы
Сколько проверок нужно добавить в первую очередь?
Нужно ли останавливать обновление отчётов, если тест упал?
Что делать, если тест постоянно срабатывает на допустимых данных?
Можно ли использовать этот SQL с другой версией dbt?
Что делать, если тест не находит ошибку или не запускается?
Как не получить шквал ложных тревог в production?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.