💯 dbt 테스트 이해하기: 기본부터 중급까지

dbt로 데이터를 변환하고 있다면 이미 잘하고 있는 겁니다. 🙌 그런데 dbt에는 데이터를 더 깨끗하고 신뢰할 수 있게 유지하는 강력한 테스트 기능도 있다는 거, 알고 계셨나요? 이번 글에서는 다음을 다룹니다: ✅ 기본 dbt 테스트 — 빠르게 적용 가능한 기본기 🚀 중급 테스트 — 사용자 정의 로직과 재사용 가능한 매크로 ✅ 기본 dbt 테스트 (Built-in) dbt는 모델의 .yml 파일 안에서 바로 사용할 수 있는 기본 테스트들을 제공합니다. 예시: version: 2 models: - name: customers description: 고객 마스터 테이블 columns: - name: customer_id tests: - not_null - unique - name: email tests: - not_null 🔧 각 테스트가 하는 일: not_null: 컬럼에 NULL 값이 없는지 확인 unique: 값이 고유한지 검증 accepted_values: 허용된 값만 포함되어 있는지 체크 relationships: 외래 키가 참조 대상 테이블과 매칭되는지 확인 accepted_values 예시 - name: status tests: - accepted_values: values: ['active', 'inactive', 'suspended'] 이런 기본 테스트들은 생산 대시보드에 오류가 반영되기 전에 단순한 데이터 이상을 빠르게 잡을 수 있습니다. ...

6월 10, 2025

PostgreSQL의 의외의 함정: Boolean, 텍스트 I/O, 그리고 ETL 이슈

PostgreSQL은 강력하고 표준을 잘 따르는 데이터베이스입니다. 하지만 의외의 작은 함정들도 있죠. 그중 하나는 바로 boolean 값을 다루는 방식, 특히 데이터를 텍스트 형식으로 내보낼 때의 이야기입니다. 🧠 PostgreSQL의 Boolean 처리 방식: 생각과 다르다 PostgreSQL은 boolean 값을 내부적으로 1비트(bit) 만으로 효율적으로 저장합니다. 예상한 대로죠. 하지만 그 값을 텍스트로 변환하거나 COPY 같은 방식으로 내보내면, 결과는 좀 다릅니다: SELECT true::text; -- 결과: 't' SELECT false::text; -- 결과: 'f' 맞습니다 — true는 't', false는 'f' 로 표현됩니다. 이건 PostgreSQL의 텍스트 I/O 기본 동작 방식인데, 이 동작 때문에 시스템 간 데이터를 주고받을 때 미묘한 버그가 생기기도 합니다. ...

6월 10, 2025

🧚 왜 dbt를 Airflow Docker 컨테이너 안에서 실행하는가

데이터 엔지니어링 파이프라인에서 dbt와 Airflow는 종종 함께 사용된다. 여기서 자주 마주하는 설계 결정이 있다: dbt를 Airflow와 어떻게 함께 실행할 것인가? dbt를 별도의 컨테이너에서 실행하고 API나 CLI 호출로 오케스트레이션할 것인가? 아니면 dbt를 Airflow의 Docker 컨테이너 안에서 직접 실행할 것인가? 둘 다 실험해본 결과, dbt를 Airflow 컨테이너 안에서 실행하는 방식을 선호한다. 이유는 다음과 같다. ✅ 하나의 컨테이너 = 하나의 환경 Airflow DAG가 동일한 컨테이너 안에서 dbt 명령어를 직접 실행한다. 이를 통해 다음이 보장된다: 동일한 Python 버전 동일한 dbt 버전 동일한 의존성 버전 (dbt 패키지, 어댑터) 컨테이너 간 네트워킹 이슈 없음 별도의 컨테이너로 분리할 경우 다음을 관리해야 한다: ...

6월 4, 2025

🧹 데이터 클렌징: 왜 스테이징 레이어에서 클렌징을 해야 하는가

실제 데이터 엔지니어링 파이프라인에서 가장 흔한 실수 중 하나는 데이터 클렌징을 너무 뒤로 미루는 것입니다. 업스트림 데이터가 깨끗할수록 다운스트림 모델은 더 단순하고 유지보수하기 쉬워집니다. 이제 하나씩 살펴보겠습니다. ✅ 기본 원칙 가능한 한 가장 이른 단계에서 데이터를 클렌징 — 이상적으로는 스테이징 레이어에서 처리해야 합니다. ✅ 그 이유 1️⃣ 책임 분리의 명확성 스테이징 모델의 역할은 다음과 같습니다: 클렌징 표준화 (정규화) 타입 캐스팅 만약 더러운 데이터를 marts까지 (예: dim_customer, fct_transaction) 넘긴다면: 다운스트림 모델이 복잡해짐 중복 필터 발생 유지보수가 어려운 취약한 코드 생성 2️⃣ Marts 레이어는 비즈니스 로직만 담당해야 한다 Marts 레이어는 오직 다음에 집중해야 합니다: ...

6월 4, 2025

🔧 ARM Mac + Docker + dbt 시작 트러블 슈팅

Airflow + dbt 프로젝트를 Docker로 세팅하던 중 발생하는 에러 메시지와 해결법. 🔍 문제1 : 플랫폼 아키텍처 mismatch 에러 메시지: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) 내 Mac은 ARM (Apple Silicon - M1/M2/M3) dbt 공식 도커 이미지는 기본적으로 amd64 (x86 기반) 결국 도커가 내부적으로 qemu 에뮬레이션을 돌리다가 Python 경로 꼬임까지 발생 → dbt dbt --version 오류로 드러남. 이건 단순 dbt 오류가 아니라 플랫폼 mismatch가 근본 원인입니다. ...

5월 30, 2025

📊 dbt가 잘하는 일 vs Python이 잘하는 일

역할 dbt가 잘함 Python이 더 낫다 정형 데이터 정제 (staging) ✅ 가능은 하지만 불편함 마트 테이블 구조 설계 ✅ 가능은 함 사용자별로 달라지는 계산 ❌ 불편함 ✅ 매우 유연함 점수화, 조건 매칭, if-else 로직 ❌ 매우 번거로움 ✅ 적합 사용자 입력 기반 필터링 ❌ 불가능 ✅ 핵심 기능 추천 이유 설명, 로직 튜닝 ❌ ✅ 완전 맞춤형 구현 가능 예를 들어 -- dbt에서는 이런 로직이 아주 힘들다... SELECT CASE WHEN user.age BETWEEN policy.min_age AND policy.max_age THEN 30 ELSE 0 END + CASE WHEN user.income < policy.income_ceiling THEN 25 ELSE 0 END + ... dbt에서는 “user”란 존재 자체가 없음 dbt는 “모든 사용자에게 동일하게 적용되는 모델”을 설계하는 도구 반면 Python에서는 사용자가 입력할 때마다 추천 결과가 달라지게 만들 수 있음 👉 dbt는 정적(Static) 모델링에 적합하지만 사용자 입력 기반의 동적(Dynamic) 추천 시스템은 Python이 더 났다. ...

5월 12, 2025