DuckDB — 파일 위에서 바로 분석하는 열 지향 엔진 · 파이프라인과 연동 · 실습
PostgreSQL 과 오가는 파이프라인
목표
DuckDB 의 postgres 확장으로 운영 PostgreSQL 표를 그 자리에서 읽고, 로컬로
복사해 집계하고, 결과를 Parquet 와 PostgreSQL 표로 내보냅니다. 파이썬 API 로
보고서 스크립트를 쓰고, 겹치는 파일을 중복 없이 덧붙이는 증분 적재를 거쳐
두 번 돌려도 같은 상태가 되는 파이프라인 스크립트로 마칩니다.
왜 중요한가
운영 DB 는 한 행을 빠르게 찾는 데 맞춰져 있지 수백만 행을 훑는 데 맞춰져 있지
않습니다. 무거운 집계를 거기서 돌리면 API 응답이 흔들립니다. DuckDB 는 운영 표를
한 번 읽어 와서 옆에서 집계할 곳이고, 결과는 다시 운영 DB 로 돌려보낼 수 있습니다.
그런데 파이프라인의 품질은 집계 속도가 아니라 멱등성으로 정해집니다 — 실패한
배치를 다시 돌릴 때 "어디까지 됐더라" 를 사람이 세어야 한다면 그 파이프라인은
사고를 기다리는 중입니다. 기본 키·INSERT OR IGNORE·CREATE OR REPLACE 가 그
부담을 표에 넘기는 방법이고, 이 실습이 그것을 몸에 익히게 합니다.
환경
PostgreSQL 은 127.0.0.1:5432, 계정 lab/lab, DB labdb 이고 시드 표
(customers·products·orders·order_items·payments)가 들어 있습니다. psql 을 쓰려면export PATH=/usr/lib/postgresql/16/bin:$PATH 를 먼저 하세요.
DuckDB 에서 붙이는 두 줄입니다. 확장은 이미지에 미리 설치돼 있어 LOAD 만 하면
됩니다 (인터넷이 없어 INSTALL 은 실패합니다). ATTACH 는 세션마다 다시 합니다.
LOAD postgres;ATTACH 'dbname=labdb user=lab password=lab host=127.0.0.1' AS pg (TYPE postgres);산출물은 /root/duck/pipe/ 아래에 둡니다 (mkdir -p /root/duck/pipe). 로컬
저장소는 /root/duck/pipe/warehouse.duckdb 한 파일입니다. 판매 파일은/opt/lab/fixtures/duck/sales/*.csv.gz (여섯 달치)와 나중에 도착한/opt/lab/fixtures/duck/incoming/2026-07-a.csv.gz · 2026-07-b.csv.gz (앞부분이
겹칩니다)입니다.
채점 전에 CLI 를 .quit 로 닫으세요. 채점기와 report.py 가 DB 파일을 읽기
전용으로 여는데, 쓰기로 열려 있으면 열지 못합니다.
단계
1. LOAD postgres · ATTACH … AS pg (TYPE postgres) 로 붙여 pg.public.orders 의 상태별 주문 수 → /root/duck/pipe/01-orders-by-status.csv (status, n)
2. /root/duck/pipe/warehouse.duckdb 에 customers, products, orders, order_items, payments 다섯 표를 복사한다
3. 복사한 표로 국가·월별 주문 수와 매출을 country_month 표로 집계 → /root/duck/pipe/03-country-month.csv (country, month, orders, revenue)
4. country_month 를 zstd Parquet 로 → /root/duck/pipe/country_month.parquet
5. /root/duck/report.py — 첫 인자 디렉터리에 매출 상위 5개 상품 05-top-products.csv (product_id, name, revenue)를 쓰는 파이썬 스크립트
6. sale_id 기본 키를 둔 sales 표에 여섯 달치를 넣고 incoming 두 파일을 중복 없이 덧붙여, 파일별 신규 행 수 → /root/duck/pipe/06-load.csv (file, new_rows)
7. country_month 를 PostgreSQL 의 public.duck_country_month 표로 되돌려 쓴다
8. 적재·집계·되돌려 쓰기를 한 번에 하는 /root/duck/pipeline.sh 를 쓰고 두 번 실행 → /root/duck/pipe/08-run.txt (sales_rows=, pg_rows=)
참고
create table 이름 as from pg.public.표— 복사. 이후 집계는 PostgreSQL 을 건드리지 않습니다.create or replace table pg.public.이름 as select …— 되돌려 쓰기.OR REPLACE가 멱등성을 만듭니다.insert or ignore into 표 select * from read_csv('…')— 기본 키가 있어야 이미 있는 행을 건너뜁니다.- 파이썬:
duckdb.connect(경로, read_only=True),con.sql(질의).write_csv(경로). - 흔한 실수:
INSTALL postgres를 치면 인터넷이 없어 실패합니다.LOAD만 하세요. - 흔한 실수: 되돌려 쓰기를
insert로 하면 돌릴 때마다 표가 두 배가 됩니다.
단계 8개
- PostgreSQL 표를 그 자리에서 읽는다
- 운영 표 다섯 개를 로컬로 복사한다
- 국가·월별 매출을 로컬에서 집계한다
- 집계를 Parquet 로 내보낸다
- 파이썬 API 로 보고서 스크립트를 쓴다
- 겹치는 파일을 중복 없이 덧붙인다
- 결과를 PostgreSQL 로 되돌려 쓴다
- 두 번 돌려도 같은 파이프라인