refactor(all): унифицированы служебные поля STG — переход на канонический нейминг
- Зачем:
- STG-слой использовал legacy-имена (batch_id, load_dttm, src_created_at_ts),
тогда как ODS/DDS/DM уже работали с каноном (_load_id, _load_ts, event_ts).
Студент видел разные имена для одного понятия — это убрано.
- Что:
- переименованы колонки в 9 STG DDL: batch_id→_load_id, load_dttm→_load_ts,
src_created_at_ts→event_ts; добавлен NOT NULL для _load_id во всех таблицах.
- обновлены 9 STG Load, 9 STG DQ, 9 ODS Load, 9 ODS DQ (INSERT/SELECT/WHERE).
- обновлены DAG-файлы bookings_to_gp_stage.py и bookings_to_gp_ods.py
(встроенный SQL резолвера, комментарии; Python-идентификаторы не тронуты).
- обновлены тесты и ~15 документов (naming_conventions, PRD, db_schema,
design-docs, qa-plan, README, TESTING и др.).
- Проверка:
- grep -rn 'load_dttm\|src_created_at_ts' sql/ airflow/ tests/ — 0 совпадений.
- make test — 4 passed.
- e2e-etl: day1 прошёл полностью, day2 стартовал без ошибок.
This commit is contained in:
@@ -119,14 +119,14 @@ def test_bookings_to_gp_stage_dag_structure():
|
||||
_assert_direct_edge(dag, load_task_id, dq_task_id)
|
||||
|
||||
# Барьеры по данным (не обязательно прямые рёбра).
|
||||
# routes_dq использует airports/airplanes текущего batch_id.
|
||||
# routes_dq использует airports/airplanes текущего _load_id.
|
||||
_assert_reachable(dag, "check_airports_dq", "check_routes_dq")
|
||||
_assert_reachable(dag, "check_airplanes_dq", "check_routes_dq")
|
||||
|
||||
# seats_dq использует airplanes текущего batch_id.
|
||||
# seats_dq использует airplanes текущего _load_id.
|
||||
_assert_reachable(dag, "check_airplanes_dq", "check_seats_dq")
|
||||
|
||||
# flights_dq использует routes текущего batch_id.
|
||||
# flights_dq использует routes текущего _load_id.
|
||||
_assert_reachable(dag, "check_routes_dq", "check_flights_dq")
|
||||
|
||||
# segments_dq проверяет наличие flights (STG-история); для первой загрузки flights должны быть до segments.
|
||||
|
||||
@@ -67,15 +67,15 @@ def test_snapshot_airports_contract_upsert_delete_and_dq() -> None:
|
||||
DROP TABLE IF EXISTS {ods_table};
|
||||
|
||||
CREATE TABLE {stg_table} (
|
||||
airport_code TEXT,
|
||||
airport_name TEXT,
|
||||
city TEXT,
|
||||
country TEXT,
|
||||
coordinates TEXT,
|
||||
timezone TEXT,
|
||||
src_created_at_ts TIMESTAMP,
|
||||
load_dttm TIMESTAMP,
|
||||
batch_id TEXT
|
||||
airport_code TEXT,
|
||||
airport_name TEXT,
|
||||
city TEXT,
|
||||
country TEXT,
|
||||
coordinates TEXT,
|
||||
timezone TEXT,
|
||||
event_ts TIMESTAMP,
|
||||
_load_ts TIMESTAMP,
|
||||
_load_id TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE {ods_table} (
|
||||
@@ -96,7 +96,7 @@ def test_snapshot_airports_contract_upsert_delete_and_dq() -> None:
|
||||
f"""
|
||||
INSERT INTO {stg_table} (
|
||||
airport_code, airport_name, city, country, coordinates, timezone,
|
||||
src_created_at_ts, load_dttm, batch_id
|
||||
event_ts, _load_ts, _load_id
|
||||
) VALUES
|
||||
('AAA', '{{"en": "Airport A", "ru": "Аэропорт A"}}', '{{"en": "City A", "ru": "Город A"}}', '{{"en": "Country A", "ru": "Страна A"}}', '(0,0)', 'UTC', now(), now(), 'batch_1'),
|
||||
('BBB', '{{"en": "Airport B", "ru": "Аэропорт B"}}', '{{"en": "City B", "ru": "Город B"}}', '{{"en": "Country B", "ru": "Страна B"}}', '(1,1)', 'UTC', now(), now(), 'batch_1');
|
||||
@@ -118,7 +118,7 @@ def test_snapshot_airports_contract_upsert_delete_and_dq() -> None:
|
||||
f"""
|
||||
INSERT INTO {stg_table} (
|
||||
airport_code, airport_name, city, country, coordinates, timezone,
|
||||
src_created_at_ts, load_dttm, batch_id
|
||||
event_ts, _load_ts, _load_id
|
||||
) VALUES
|
||||
('AAA', '{{"en": "Airport A v2", "ru": "Аэропорт A v2"}}', '{{"en": "City A", "ru": "Город A"}}', '{{"en": "Country A", "ru": "Страна A"}}', '(0,0)', 'UTC', now(), now(), 'batch_2'),
|
||||
('CCC', '{{"en": "Airport C", "ru": "Аэропорт C"}}', '{{"en": "City C", "ru": "Город C"}}', '{{"en": "Country C", "ru": "Страна C"}}', '(2,2)', 'UTC', now(), now(), 'batch_2');
|
||||
|
||||
@@ -28,7 +28,7 @@ def test_snapshot_dq_checks_extra_keys() -> None:
|
||||
|
||||
|
||||
def test_ods_batch_resolver_uses_consistent_snapshot_batches() -> None:
|
||||
"""Резолвер батча должен искать batch_id, общий для всех snapshot-таблиц STG."""
|
||||
"""Резолвер батча должен искать _load_id, общий для всех snapshot-таблиц STG."""
|
||||
dag_code = _read("airflow/dags/bookings_to_gp_ods.py")
|
||||
|
||||
for table_name in ("stg.airports", "stg.airplanes", "stg.routes", "stg.seats"):
|
||||
|
||||
Reference in New Issue
Block a user