7분
문지기는 적재 전에 선다
ETL 파이프라인
문지기는 적재 전에 선다
ETL 파이프라인 > ETL 파이프라인
학습 목표
- L2 검증의 실행 위치를 판단한다
- 통과분과 거부분을 사유와 함께 분리한다
L2 검증의 배치 — 문지기는 적재 전에
코스 2에서 설계하고 에디션 한계로 확장된 L2 검증(존재성·형식·범위·카디널리티)의 실행 위치는 정제 단계, 즉 적재 전입니다.
⚠️ DB에 들어간 뒤 청소하는 것(load-then-clean)은 금물입니다. 오염된 그래프 위에서 도는 CQ는 이미 거짓을 답하고 있습니다. 청소하는 동안에도 누군가는 그 그래프에 질문을 던집니다.
def validate_l2(df: pd.DataFrame) -> tuple[pd.DataFrame, pd.DataFrame]:
"""통과분과 거부분(사유 포함)을 분리 반환"""
df = df.copy(); df["reject_reason"] = None
df.loc[df["callSign"].isna(), "reject_reason"] = "존재성: callSign 없음" # L2 이관분
bad_time = pd.to_datetime(df["arrivalUtc"], errors="coerce").isna()
df.loc[bad_time & df["reject_reason"].isna(), "reject_reason"] = "형식: 시각 파싱 실패"
ok = df[df["reject_reason"].isna()].drop(columns=["reject_reason"])
rejected = df[df["reject_reason"].notna()]
return ok, rejected
주목할 점 — 첫 번째 검사가 바로 코스 2에서 L1(DB 제약)에 넣었다가 Community 한계로 L2로 이관된 존재성 검사입니다. 설계 문서의 한 줄 개정이 여기서 코드 한 줄이 됐습니다.
거부 리포트는 축적합니다
사유별 건수·비율을 매 적재마다 자동 산출해 쌓습니다. 이 시계열이 "원천 데이터 품질이 좋아지는가"라는 메타 CQ의 답이 됩니다.
한 번의 거부 목록은 오늘의 문제지만, 여섯 달치 거부 시계열은 원천 기관과 협의할 근거입니다.
실습
validate_l2에 자기 매핑 시트의 검증 열을 전부 옮깁니다.- 거부율을 사유별로 집계합니다. ⚠️ 거부율이 30%를 넘으면 검증이 아니라 매핑이 틀렸을 가능성을 먼저 의심하세요.
- 거부분을
rejected/에 사유와 함께 저장합니다(헌법 2조).
에디터 로딩 중...