Проверка/рецензирование доработки
This commit is contained in:
@@ -29,4 +29,6 @@ CREATE TABLE IF NOT EXISTS stg.tickets (
|
||||
batch_id TEXT
|
||||
)
|
||||
WITH (appendonly=true, orientation=row, compresstype=zlib, compresslevel=1)
|
||||
DISTRIBUTED BY (ticket_no);
|
||||
-- Распределяем по book_ref, чтобы джойны tickets → bookings по book_ref были без motion.
|
||||
DISTRIBUTED BY (book_ref);
|
||||
|
||||
|
||||
+69
-38
@@ -1,52 +1,83 @@
|
||||
-- Проверки качества данных для tickets
|
||||
|
||||
-- Проверка 1: совпадение количества билетов в источнике и STG
|
||||
DO $$
|
||||
DECLARE
|
||||
v_source_count BIGINT;
|
||||
v_stg_count BIGINT;
|
||||
v_batch_id TEXT := '{{ run_id }}'::text;
|
||||
v_prev_ts TIMESTAMP;
|
||||
v_source_count BIGINT;
|
||||
v_stg_count BIGINT;
|
||||
v_orphan_count BIGINT;
|
||||
v_null_count BIGINT;
|
||||
BEGIN
|
||||
-- Количество в источнике (новые билеты)
|
||||
-- Используем только внешние таблицы: stg.tickets_ext + stg.bookings_ext
|
||||
SELECT COUNT(*) INTO v_source_count
|
||||
-- Опорная метка: максимум src_created_at_ts среди предыдущих батчей
|
||||
SELECT max(src_created_at_ts)
|
||||
INTO v_prev_ts
|
||||
FROM stg.tickets
|
||||
WHERE batch_id <> v_batch_id
|
||||
OR batch_id IS NULL;
|
||||
|
||||
-- Количество в источнике (новые билеты в том же окне инкремента, что и загрузка)
|
||||
SELECT COUNT(*)
|
||||
INTO v_source_count
|
||||
FROM stg.tickets_ext AS t
|
||||
JOIN stg.bookings_ext AS b ON t.book_ref = b.book_ref
|
||||
WHERE b.book_date > COALESCE(
|
||||
(SELECT max(src_created_at_ts) FROM stg.tickets
|
||||
WHERE batch_id <> '{{ run_id }}'::text OR batch_id IS NULL),
|
||||
TIMESTAMP '1900-01-01 00:00:00'
|
||||
);
|
||||
WHERE b.book_date > COALESCE(v_prev_ts, TIMESTAMP '1900-01-01 00:00:00');
|
||||
|
||||
IF v_source_count = 0 THEN
|
||||
RAISE EXCEPTION
|
||||
'В источнике tickets_ext нет строк для окна инкремента (book_date > %). Проверьте генерацию данных (таск generate_bookings_day).',
|
||||
COALESCE(v_prev_ts, TIMESTAMP '1900-01-01 00:00:00');
|
||||
END IF;
|
||||
|
||||
-- Количество в STG (текущий батч)
|
||||
SELECT COUNT(*) INTO v_stg_count
|
||||
SELECT COUNT(*)
|
||||
INTO v_stg_count
|
||||
FROM stg.tickets
|
||||
WHERE batch_id = '{{ run_id }}'::text;
|
||||
WHERE batch_id = v_batch_id;
|
||||
|
||||
-- Проверка совпадения
|
||||
IF v_source_count <> v_stg_count THEN
|
||||
RAISE EXCEPTION 'DQ FAILED: несовпадение количества билетов. Источник: %, STG: %',
|
||||
v_source_count, v_stg_count;
|
||||
ELSE
|
||||
RAISE NOTICE 'DQ PASSED: количество билетов совпадает (%)', v_stg_count;
|
||||
RAISE EXCEPTION
|
||||
'DQ FAILED: несовпадение количества билетов. Источник: %, STG (batch_id=%): %',
|
||||
v_source_count,
|
||||
v_batch_id,
|
||||
v_stg_count;
|
||||
END IF;
|
||||
|
||||
-- Проверка ссылочной целостности: все tickets должны иметь соответствующие bookings в этом же STG
|
||||
SELECT COUNT(*)
|
||||
INTO v_orphan_count
|
||||
FROM stg.tickets AS t
|
||||
WHERE t.batch_id = v_batch_id
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM stg.bookings AS b
|
||||
WHERE b.book_ref = t.book_ref
|
||||
);
|
||||
|
||||
IF v_orphan_count <> 0 THEN
|
||||
RAISE EXCEPTION
|
||||
'DQ FAILED: найдены tickets без соответствующих bookings (batch_id=%): %',
|
||||
v_batch_id,
|
||||
v_orphan_count;
|
||||
END IF;
|
||||
|
||||
-- Проверка обязательных полей
|
||||
SELECT COUNT(*)
|
||||
INTO v_null_count
|
||||
FROM stg.tickets AS t
|
||||
WHERE t.batch_id = v_batch_id
|
||||
AND (t.ticket_no IS NULL OR t.book_ref IS NULL);
|
||||
|
||||
IF v_null_count <> 0 THEN
|
||||
RAISE EXCEPTION
|
||||
'DQ FAILED: найдены tickets с NULL в обязательных полях (batch_id=%): %',
|
||||
v_batch_id,
|
||||
v_null_count;
|
||||
END IF;
|
||||
|
||||
RAISE NOTICE
|
||||
'DQ PASSED: tickets ок (batch_id=%): source=% stg=%',
|
||||
v_batch_id,
|
||||
v_source_count,
|
||||
v_stg_count;
|
||||
END $$;
|
||||
|
||||
-- Проверка 2: ссылочная целостность (все ticket_no должны иметь соответствующие book_ref)
|
||||
SELECT
|
||||
COUNT(*) AS orphan_tickets
|
||||
FROM stg.tickets
|
||||
WHERE batch_id = '{{ run_id }}'::text
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM stg.bookings
|
||||
WHERE stg.bookings.book_ref = stg.tickets.book_ref
|
||||
);
|
||||
-- Ожидаемое значение: 0
|
||||
|
||||
-- Проверка 3: отсутствие NULL в обязательных полях
|
||||
SELECT
|
||||
COUNT(*) AS null_tickets
|
||||
FROM stg.tickets
|
||||
WHERE batch_id = '{{ run_id }}'::text
|
||||
AND (ticket_no IS NULL OR book_ref IS NULL);
|
||||
-- Ожидаемое значение: 0
|
||||
|
||||
@@ -32,9 +32,8 @@ WHERE b.book_date > COALESCE(
|
||||
TIMESTAMP '1900-01-01 00:00:00'
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
-- Защита от дубликатов в рамках одного батча
|
||||
-- Защита от дублей: ticket_no в источнике уникален, и в stg его не дублируем.
|
||||
SELECT 1
|
||||
FROM stg.tickets AS t
|
||||
WHERE t.batch_id = '{{ run_id }}'::text
|
||||
AND t.ticket_no = ext.ticket_no
|
||||
WHERE t.ticket_no = ext.ticket_no
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user