Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Data quality: проверки качества данных в пайплайне

Data quality: как проверять данные до того, как их увидит бизнес

Проверки качества данных: контракты, тесты уникальности и полноты, пороговые метрики, блокирующие и предупреждающие проверки — практика в dbt и Airflow.

Прямой ответ

Data quality — практика проверки данных на соответствие ожиданиям до того, как они попадут в отчёты и модели. Без проверок ошибка источника превращается в неверное бизнес-решение, а обнаруживается через недели, когда «цифры не сходятся».

Измерения качества, которые стоит проверять систематически:

  1. Полнота (completeness). Нет ли пропусков в обязательных полях; не «схлопнулся» ли объём данных за период.
  2. Уникальность (uniqueness). Нет ли дублей по бизнес-ключу.
  3. Валидность (validity). Значения попадают в допустимый домен: статусы из справочника, даты в разумном диапазоне, суммы неотрицательны.
  4. Согласованность (consistency). Итоги сходятся между слоями: сумма по витрине равна сумме по источнику с учётом фильтров.
  5. Своевременность (timeliness). Данные за период пришли в ожидаемое время.
  6. Точность (accuracy). Выборочная сверка с эталонным источником.

Типы проверок по последствию:

  • Блокирующие (fail). Пайплайн останавливается, данные дальше не идут. Для нарушений, делающих данные непригодными: дубли первичного ключа, пустая таблица, отрицательные суммы.
  • Предупреждающие (warn). Пайплайн продолжается, создаётся оповещение. Для дрейфа: доля пропусков выросла, объём упал на 20 %.
  • Информационные (metric). Метрика собирается и отображается на дашборде без алерта.

Ключевой принцип: проверки живут рядом с данными и выполняются в том же пайплайне, а не «когда аналитик заметит». Это реализуется тестами в dbt, задачами в Airflow или отдельным сервисом валидации в ETL.

Практика: конкретные тесты

dbt-тесты в схеме модели:

models:
  - name: orders
    columns:
      - name: order_id
        tests: [unique, not_null]
      - name: status
        tests:
          - accepted_values:
              values: ['new', 'paid', 'shipped', 'cancelled']
      - name: total
        tests:
          - dbt_utils.accepted_range:
              min_value: 0
              inclusive: true
    tests:
      - dbt_utils.unique_combination_of_columns:
          combination_of_columns: [order_id, line_no]

Проверка объёма (защита от «тихого» исчезновения данных):

-- ожидаем не менее 80% от среднего за предыдущие 7 дней
WITH today AS (SELECT count(*) AS c FROM orders WHERE created_at >= CURRENT_DATE),
     base   AS (SELECT count(*) / 7.0 AS avg_c FROM orders
                WHERE created_at >= CURRENT_DATE - 7 AND created_at < CURRENT_DATE)
SELECT CASE WHEN today.c < 0.8 * base.avg_c THEN 'FAIL' ELSE 'OK' END AS status
FROM today, base;

Сверка между слоями:

SELECT abs(s.revenue - r.revenue) AS diff
FROM mart_daily_sales s
JOIN (SELECT date_trunc('day', created_at) AS d, sum(total) AS revenue
      FROM orders GROUP BY 1) r ON r.d = s.day
WHERE s.day = CURRENT_DATE - 1;

Рекомендации по внедрению:

  1. Начинайте с ключей и объёмов. Уникальность первичного ключа, отсутствие пустых обязательных полей и контроль объёма ловят большинство серьёзных инцидентов при минимальных затратах.
  2. Разделяйте жёсткость. Блокирующие тесты держите только для действительно критичных нарушений: иначе пайплайн будет стоять из-за косметических проблем, и команда начнёт обходить проверки.
  3. Фиксируйте пороги как код. «Не менее 80 % от среднего» должно быть в репозитории, а не в голове инженера.
  4. Собирайте историю проверок. Результаты тестов — это данные: по ним видно дрейф качества и момент, когда проблема началась.

Практический сценарий: отчёт «сломался» из-за дублей в источнике

Контекст: ежедневная витрина продаж; утром выручка за вчера оказалась вдвое выше обычной.

  1. Обнаружение. Алерт на объём сработал: число строк выросло на 96 %. Без такого алерта ошибку заметили бы на совещании.
  2. Диагностика. Проверка уникальности по order_id возвращает 180 тысяч дублей. Причина — источник начал присылать полный снапшот вместо инкремента, а загрузка не различала режимы.
  3. Локализация. Дубли появились только в слое raw; слой curated строится через row_number() по бизнес-ключу и частично компенсировал проблему, но не во всех моделях.
  4. Исправление. (а) Добавляем блокирующий тест уникальности на вход слоя raw; (б) в загрузке различаем снапшот и инкремент по признаку в сообщении; (в) витрину пересчитываем за затронутый период из проверенного среза.
  5. Профилактика. Вводим правило: каждая новая модель получает минимум три теста — уникальность ключа, отсутствие пустых обязательных полей, контроль объёма. Регрессионные проверки данных включаем в интеграционные тесты на Testcontainers.

Результат: инцидент обнаружен за минуты, а не дни; повторное появление дублей останавливает пайплайн до витрины. Вывод: качество данных — это инженерная практика с тестами и порогами, а не разовая «чистка».

Где хранить результаты проверок. Результаты тестов стоит сохранять как данные: таблица с датой, моделью, именем проверки, статусом и числом нарушенных строк. Это даёт три возможности: видеть момент начала проблемы, а не только факт её наличия; строить тренды доли нарушений и замечать медленный дрейф; объяснять исторические расхождения — например, показать, что витрина за прошлый месяц строилась в момент, когда проверка объёма уже предупреждала о неполноте данных.

Проверки на границе систем. Отдельный класс — проверки входного контракта: структура сообщения, наличие обязательных полей, допустимые значения справочников. Их выполняют до загрузки в слой raw, иначе испорченные данные успевают распространиться по всем производным моделям, и область исправления вырастает с одной задачи до всего хранилища.

FAQ

Сколько проверок достаточно? Минимум на модель: уникальность ключа, непустота обязательных полей, допустимые значения статусов и контроль объёма. Дальше добавляйте проверки по мере появления инцидентов — каждый инцидент должен оставлять после себя новый тест.

Что делать, если проверка падает, а данные нужны срочно? Разделите контур: блокирующая проверка останавливает публикацию витрины, но сырые данные сохраняются. Если бизнес принимает решение идти с известной проблемой, это фиксируется как исключение с датой и причиной, а не как отключение теста.

Чем data quality отличается от тестирования кода пайплайна? Тесты кода проверяют логику трансформации на фиксированных данных. Проверки качества проверяют сами данные, которые меняются каждый день. Оба класса нужны: код может быть корректным, а вход — испорченным.

Можно ли проверять качество в потоковой обработке? Да, но с другими порогами: потоковые проверки обычно мягче (доля аномалий за окно), потому что полный срез данных ещё не доступен. Жёсткие проверки переносят на микропакеты или на периодическую сверку с эталоном — например, с потоком CDC.

Источники: dbt docs (data tests), Airflow docs (DAGs), Wikipedia (data quality) — ссылки в шапке.