pip install duckdb
(반드시 1.3 버전 이상 설치)import duckdb as dd
# In Memory 상태에서 데이터베이스 연결 생성
mem_con = dd.connect()
# Extension들 설치
mem_con.execute("INSTALL postgres")
mem_con.execute("INSTALL mysql")
mem_con.execute("INSTALL ducklake")
mem_con.execute("INSTALL httpfs")
DuckDB
, Sqlite
, PostgreSQL
, MySQL
PostgreSQL
과 MySQL
을 각각 활용해보도록 하겠습니다.PostgreSQL
, MySQL
컨테이너가 생성됩니다.services:
mysql:
image: mysql
container_name: mysql_db
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_USER=hyunsoo
- MYSQL_PASSWORD=velog
- MYSQL_DATABASE=ducklake_catalog
postgres:
image: postgres:16
container_name: postgres_db
ports:
- "5432:5432"
environment:
- POSTGRES_USER=hyunsoo
- POSTGRES_PASSWORD=velog
- POSTGRES_DB=ducklake_catalog
실행 명령 → docker compose up -d
secret_gcs = """
CREATE SECRET (
TYPE GCS,
KEY_ID 'ABCDE',
SECRET 'ABCDESECRET'
);
"""
mem_con.execute(secret_gcs)
secret_s3 = """
CREATE SECRET (
TYPE s3,
PROVIDER config,
KEY_ID 'AKIAIOSFODNN7EXAMPLE',
SECRET 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
REGION 'ap-northeast-2'
);
"""
mem_con.execute(secret_s3)
mem_con.execute("FROM duckdb_secrets()").df()
PostgreSQL
과 MySQL
역시 SECRET으로 등록해주어야 합니다.pg_conn = """
CREATE SECRET (
TYPE postgres,
HOST '127.0.0.1',
PORT 5432,
DATABASE ducklake_catalog,
USER 'codeit',
PASSWORD 'sprint'
);
"""
mem_con.execute(pg_conn)
mysql_conn = """
CREATE SECRET (
TYPE mysql,
HOST '127.0.0.1',
PORT 3306,
DATABASE ducklake_catalog,
USER 'codeit',
PASSWORD 'sprint'
);
"""
mem_con.execute(mysql_conn)
ATTACH
명령어를 통해 DuckLake 설정이 가능하며, DATA_PATH
다음에는 DuckLake에서 관리되는 데이터가 저장될 경로를 넣어주시면 됩니다. 아래 예시와 같이 로컬 경로, 클라우드 스토리지 경로 등 사용 환경에 맞게 설정이 가능합니다./home/ducklake/data/
s3://aws_ducklake_bucket/data_dir/
gs://gcs_ducklake_bucket/data_dir/
gs://hyunsoo_de_bucket/ducklake/postgres/
경로를 데이터 저장소로 사용해보겠습니다.ATTACH 'ducklake:<연결 DB 종류>:dbname=<데이터베이스 이름>'
AS <생성할 DB 이름>(DATA_PATH <객체 저장소 경로>);
ducklake_conn = """
ATTACH 'ducklake:postgres:dbname=ducklake_catalog'
AS my_ducklake(DATA_PATH 'gs://hyunsoo_de_bucket/ducklake/postgres/');
"""
mem_con.execute(ducklake_conn)
ducklake_conn = """
ATTACH 'ducklake:mysql:db=ducklake_catalog'
AS my_ducklake(DATA_PATH 'gs://hyunsoo_de_bucket/ducklake/mysql/');
"""
mem_con.execute(ducklake_conn)
ducklake_catalog
DB를 조회해보면 아래와 같이 DuckLake 관련 메타 테이블들이 세팅되어 있는 것을 확인할 수 있습니다._query = """
FROM read_parquet('gs://hyunsoo_de_bucket/dataset/emp.parquet')
"""
mem_con.execute(_query).df()
mem_con.execute("SHOW DATABASES").df()
my_ducklake
데이터베이스를 선택한 후 CREATE TABLE ~ AS
쿼리를 통해 기존에 있는 테이블을 기반으로 새로운 테이블을 생성합니다.## my_ducklake 데이터베이스 사용 설정
mem_con.execute("USE my_ducklake")
## 새로운 테이블 생성
create_table = """
CREATE TABLE duck_emp
AS
SELECT * FROM read_parquet('gs://hyunsoo_de_bucket/dataset/emp.parquet')
"""
mem_con.execute(create_table)
테이블 생성 후 등록한 DATA_PATH
경로를 확인해보면 main/<테이블 이름>
디렉토리가 새롭게 생성되면서 데이터가 parquet
파일 형태로 저장이 된 것을 확인할 수 있습니다.
(‼️ 위 저장되는 디렉토리 구조는 MacOS 기준이며, 실습 결과 Windows와 Linux 플랫폼에서는 디렉토리 구조가 약간 달랐습니다. ‼️)
또한 메타 테이블의 ducklake_table
을 조회해보면 아래와 같이 방금 생성한 duck_emp
테이블을 확인할 수 있습니다.
## 1) 새로운 컬럼 추가(new_col)
mem_con.execute("ALTER TABLE duck_emp ADD COLUMN new_col INT DEFAULT 0")
## 2) UPDATE
mem_con.execute("UPDATE duck_emp SET new_col = 1 WHERE Salary >= 100000")
## 3) DELETE
mem_con.execute("DELETE FROM duck_emp WHERE Salary < 50000")
ducklake_snapshot
, ducklake_snapshot_changes
테이블을 조회해보면 됩니다.mem_con.execute("FROM my_ducklake.snapshots()").df()
mem_con.execute("SELECT * FROM duck_emp AT (VERSION => 3)").df()
2025-07-04 05:43:49.371+00
→ 이 시점에서의 테이블 데이터를 보여줍니다.mem_con.execute("SELECT * FROM duck_emp AT (TIMESTAMP => '2025-07-04 05:43:49.371+00')").df()