Python·Arrow·Polars·BI
Python API, Arrow zero-copy, Pandas/Polars replacement scan, BI 연결을 실무 분석 흐름으로 정리합니다.
핵심 요약
- DuckDB는 SQL과 Python 생태계를 한 프로세스에서 연결해 Pandas·Polars·Arrow 객체를 table처럼 질의하고 결과를 DataFrame/Arrow로 돌려받습니다.
- module-level duckdb.sql()은 전역 in-memory connection을 쓰므로 운영 notebook·batch에서는 명시 connection을 권장합니다.
- replacement scan은 Python 변수명을 SQL에서 그대로 참조하되 read-only이며, DataFrame에 INSERT/UPDATE를 하는 게 아니라 scan만 합니다.
- Arrow Dataset은 projection/filter pushdown이 가능하고 to_arrow_table()로 반환하면 Pandas 변환 비용을 늦추고 Arrow-native 도구와 연결하기 쉽습니다.
- 팀 표준이 SQL이면 DuckDB를 중심에 두고 expression 중심 feature engineering은 Polars를 함께 쓰며, BI는 read-only .duckdb/curated Parquet와 batch refresh로 고정합니다.
DuckDB가 생산성에서 가장 빛나는 지점은 SQL과 Python 분석 생태계를 한 프로세스 안에서 연결한다는 점입니다. Pandas, Polars, Arrow 객체를 table처럼 질의하고, 결과는 다시 DataFrame이나 Arrow Table로 돌려받습니다.
Python 기본 패턴
import duckdb
con = duckdb.connect("analytics.duckdb")
con.execute("SET threads = 4")
con.execute("SET memory_limit = '8GB'")
df = con.execute("""
SELECT customer_id, sum(amount) AS revenue
FROM read_parquet('curated/orders/*.parquet')
GROUP BY customer_id
""").df()module-level duckdb.sql()은 전역 in-memory connection을 사용합니다. notebook 초반 탐색에는 편하지만, 운영 notebook이나 batch에서는 명시 connection을 권장합니다.
Replacement scan
Pandas DataFrame, Polars DataFrame, Arrow Table은 Python 변수명 그대로 SQL에서 참조할 수 있습니다.
import duckdb
import pandas as pd
customers = pd.DataFrame({"customer_id": ["c1", "c2"], "segment": ["team", "pro"]})
duckdb.sql("""
SELECT segment, count(*) AS customers
FROM customers
GROUP BY ALL
""").df()이 방식은 read-only입니다. DataFrame에 INSERT/UPDATE를 하는 게 아니라, DuckDB가 해당 객체를 scan하는 것뿐입니다.
Arrow Dataset
Arrow Dataset은 directory of Parquet files를 가리키고, DuckDB는 projection/filter를 pushdown할 수 있습니다.
import duckdb
import pyarrow.dataset as ds
dataset = ds.dataset("curated/orders", format="parquet")
result = duckdb.connect().execute("""
SELECT order_date, sum(amount) AS revenue
FROM dataset
WHERE order_date >= DATE '2026-01-01'
GROUP BY ALL
""").to_arrow_table()Arrow로 반환하면 Pandas 변환 비용을 늦출 수 있고, 다른 Arrow-native 도구와 연결하기 쉽습니다.
Polars와 역할 분담
| 작업 | DuckDB | Polars |
|---|---|---|
| SQL 기반 join/aggregate | 강함 | 가능 |
| lazy dataframe pipeline | 가능하지만 주력 아님 | 강함 |
| Parquet lake 탐색 | 강함 | 강함 |
| BI/SQL 공유 | 강함 | 약함 |
| Python expression 변환 | 약함 | 강함 |
팀 표준이 SQL이면 DuckDB를 중심에 두고, Python expression이 많은 feature engineering은 Polars를 함께 씁니다.
BI 연결
DuckDB는 ODBC/JDBC와 여러 third-party BI 도구에서 사용할 수 있습니다. BI 운영에서는 다음을 고정합니다.
| 항목 | 기준 |
|---|---|
| 데이터 파일 | read-only .duckdb 또는 curated Parquet |
| refresh | batch publish 이후 BI refresh |
| 권한 | OS/cloud storage 권한으로 제한 |
| 쿼리 | BI 사용자가 임의 extension/network access를 열지 못하게 격리 |