Skip to main content
이 문서는 데이터 엔지니어링 섹션의 일부입니다.

왜 데이터 품질 관리가 필요한가?

데이터 파이프라인에서 가장 흔한 문제는 **“Garbage In, Garbage Out”**입니다. 소스 데이터에 결측값, 잘못된 형식, 비즈니스 규칙 위반 등이 포함되면, 이를 기반으로 만들어진 리포트와 ML 모델의 결과도 신뢰할 수 없게 됩니다.
💡 전통적으로 데이터 품질 검증은 파이프라인 코드 곳곳에 if 문이나 filter() 로직을 수동으로 삽입해야 했습니다. 이 방식은 유지보수가 어렵고, 품질 규칙의 전체 현황을 한눈에 파악하기 어렵습니다. SDP의 Expectations 는 이 문제를 선언적(Declarative) 으로 해결합니다.
검증 결과동작설명
통과정상 데이터 → 다음 단계데이터가 품질 기준을 충족합니다
WARN경고 기록 + 데이터 포함위반 사항을 기록하되 데이터는 통과시킵니다
DROP위반 행 제거 (격리 가능)위반된 행을 제거합니다
FAIL파이프라인 중지파이프라인 실행을 즉시 중지합니다

Expectations란?

Expectations 는 SDP(Spark Declarative Pipelines)에서 데이터 품질 규칙을 선언적으로 정의하는 기능입니다. SQL의 CONSTRAINT처럼 테이블 정의에 품질 규칙을 직접 명시하며, 각 규칙에 대해 부적합 데이터를 어떻게 처리할지(경고, 삭제, 파이프라인 중지)를 지정할 수 있습니다.

핵심 특징

특징설명
선언적 정의테이블 DDL 안에 CONSTRAINT ... EXPECT (조건) 형태로 작성합니다
자동 모니터링매 업데이트마다 통과/위반 건수가 자동으로 기록됩니다
유연한 처리규칙별로 WARN, DROP ROW, FAIL UPDATE 중 선택할 수 있습니다
파이프라인 통합별도 도구 없이 SDP 파이프라인 안에서 바로 사용할 수 있습니다

위반 처리 방식 3가지

Expectations는 데이터 품질 위반 시 세 가지 행동 을 지원합니다. 비즈니스 요구사항에 따라 규칙별로 다르게 설정할 수 있습니다.

상세 비교

방식SQL 키워드Python 데코레이터위반 시 동작사용 시나리오
경고만ON VIOLATION WARN (기본)@dlt.expect("name", "condition")위반 레코드를 포함 하되, 위반 건수를 기록합니다모니터링 목적, 신규 규칙 테스트
행 삭제ON VIOLATION DROP ROW@dlt.expect_or_drop("name", "condition")위반 레코드를 결과에서 제외 합니다데이터 품질 보장이 필요한 Silver/Gold 계층
파이프라인 중지ON VIOLATION FAIL UPDATE@dlt.expect_or_fail("name", "condition")위반 발생 시 파이프라인을 즉시 중지 합니다치명적 오류(스키마 위반, 필수값 누락 등)
⚠️ FAIL UPDATE 사용 시 주의: 파이프라인이 중지되면 해당 업데이트의 모든 테이블 갱신이 중단됩니다. 복구하려면 문제 데이터를 수정한 후 파이프라인을 다시 실행해야 합니다.

동작 흐름 비교

위반 처리 모드별 동작 비교
모드통과 시위반 시
WARN테이블에 저장테이블에 저장 + 위반 메트릭 기록
DROP ROW테이블에 저장레코드 제거 + 위반 메트릭 기록
FAIL UPDATE테이블에 저장파이프라인 즉시 중지 + 업데이트 실패

Expectation 정의 문법

SQL 문법

SQL에서는 CREATE OR REFRESH STREAMING TABLE 또는 CREATE OR REFRESH MATERIALIZED VIEW 정의 안에 CONSTRAINT 절로 Expectation을 선언합니다.
CREATE OR REFRESH STREAMING TABLE silver_orders (
    -- 경고만 (모니터링용)
    CONSTRAINT valid_email
        EXPECT (email RLIKE '^[^@]+@[^@]+\\.[^@]+$')
        ON VIOLATION WARN,

    -- 위반 행 삭제 (품질 보장)
    CONSTRAINT valid_order_id
        EXPECT (order_id IS NOT NULL)
        ON VIOLATION DROP ROW,

    CONSTRAINT positive_amount
        EXPECT (amount > 0)
        ON VIOLATION DROP ROW,

    -- 파이프라인 중지 (치명적 오류)
    CONSTRAINT valid_date
        EXPECT (order_date >= '2020-01-01')
        ON VIOLATION FAIL UPDATE
)
AS SELECT * FROM STREAM(bronze_orders);
💡 ON VIOLATION WARN은 기본값이므로, 생략하면 자동으로 WARN이 적용됩니다. 명시적으로 작성하는 것이 가독성에 좋습니다.

Python 문법

Python에서는 @dlt.expect, @dlt.expect_or_drop, @dlt.expect_or_fail 데코레이터를 사용합니다.
import dlt
from pyspark.sql.functions import col, expr

# 경고만 (WARN)
@dlt.table(comment="정제된 주문 데이터")
@dlt.expect("valid_order_id", "order_id IS NOT NULL")
@dlt.expect("valid_email", "email RLIKE '^[^@]+@[^@]+\\\\.[^@]+$'")
def silver_orders():
    return (
        dlt.read_stream("bronze_orders")
           .select(
               col("order_id").cast("bigint"),
               col("amount").cast("decimal(12,2)"),
               col("order_date").cast("timestamp"),
               col("email")
           )
    )

# 행 삭제 (DROP)
@dlt.table()
@dlt.expect_or_drop("positive_amount", "amount > 0")
@dlt.expect_or_drop("valid_status", "status IN ('pending', 'completed', 'cancelled')")
def silver_orders_clean():
    return dlt.read_stream("silver_orders")

# 파이프라인 중지 (FAIL)
@dlt.table()
@dlt.expect_or_fail("valid_date", "order_date >= '2020-01-01'")
def silver_orders_strict():
    return dlt.read_stream("silver_orders")