DuckDB で Apache Iceberg テーブルに書き込む - ノートPCで動くローカル・レイクハウス
2026年のデータエンジニアリングでいちばん語られているのが「レイクハウスの truth は Iceberg テーブルに置き、compute は差し替え可能にする」というパターンだ。そして compute 側の主役として、クラウドの ClickHouse と並んでノートPCで完結する DuckDB が急速に採用を伸ばしている。
これまで DuckDB の Iceberg 対応は「読むだけ」だった。潮目が変わったのが DuckDB 1.4.0 で、Iceberg REST カタログ経由の書き込み(CREATE TABLE / INSERT)に対応し、続く 1.4.2 で UPDATE / DELETE まで入った。つまり別途 Spark や Trino を立てなくても、DuckDB 単体で Iceberg テーブルのライフサイクルを回せるようになった。本稿では 2026年6月時点の最新安定版 DuckDB 1.5.4(LTS は 1.4.5)を使い、ローカルにミニ・レイクハウスを組んで実際に書き込む。
仕組みの要点
Iceberg テーブルへの書き込みは、必ずカタログ経由で行う。DuckDB は Iceberg REST Catalog に ATTACH し、すべての書き込みはカタログにコミットされて新しいスナップショットになる。catalog なしの iceberg_scan() は読み取り専用なので、書きたいなら REST カタログが要る。
ローカルで再現するには次の 3 つを Docker で立てる。
- iceberg-rest-fixture: Apache 公式の軽量 REST カタログ実装(ポート 8181)
- MinIO: S3 互換オブジェクトストレージ(データ本体の置き場)
- DuckDB CLI: クエリエンジン(ホスト側で動かす)
DuckDB は「カタログにメタデータを問い合わせ、データファイルは S3(MinIO) に直接読み書きする」という二段構えで動くので、DuckDB 側には REST エンドポイントと MinIO の S3 認証情報の両方を渡す。
実際に試す
前提
- Docker / Docker Compose が動く環境(macOS / Linux)
- DuckDB CLI 1.4.0 以上(本稿は 1.5.4 で確認)
- ポート 8181 / 9000 / 9001 が空いていること
DuckDB CLI が未導入なら、公式のインストールスクリプトが手軽。
1 | |
1. ローカルのカタログと MinIO を Docker で起動
作業用ディレクトリに次の docker-compose.yml を置く。
1 | |
起動する。
1 | |
mc サービスが MinIO 上に warehouse バケットを作り、iceberg-rest が http://localhost:8181 で REST カタログを提供する。
2. DuckDB からカタログに ATTACH する
DuckDB CLI を起動して、拡張のロード・MinIO 用 S3 シークレット作成・カタログへの ATTACH を順に流す。
1 | |
AUTHORIZATION_TYPE 'none' がローカル開発用のポイント。本番の REST カタログはたいてい OAuth2 なので、そこは CREATE SECRET ... (TYPE iceberg, CLIENT_ID ..., CLIENT_SECRET ...) に置き換える。
3. スキーマとテーブルを作って書き込む
ここからは普通の SQL。カタログ名 lake を頭に付けるだけで、実体は Iceberg テーブルとして MinIO に書かれる。
1 | |
期待される出力:
1 | |
4. UPDATE / DELETE も効く(1.4.2 以降)
行更新・削除もカタログ経由で新しいスナップショットとしてコミットされる。
1 | |
期待される出力(id=1 は前段の削除条件に該当するため消え、id=3 だけが残る):
1 | |
5. スナップショット履歴を確認する
Iceberg の強みはスナップショット単位の履歴管理。ここまでで INSERT / UPDATE / DELETE の 3 回コミットしたので、3 つのスナップショットが並ぶはずだ。
1 | |
各コミットが 1 行ずつ、sequence_number が 1, 2, 3 と増えて記録される。これがそのまま監査ログとタイムトラベルの土台になる。
後片付け
1 | |
まとめ
DuckDB 1.4 系以降は、Spark を立てずにノートPC一台で Iceberg テーブルを読み書きできる。ローカルで REST カタログ + MinIO を Docker で用意すれば、本番のクラウド・レイクハウス(S3 + Glue/Lakekeeper 等の REST カタログ)とほぼ同じ SQL がそのまま通る。開発・検証を手元で回し、ATTACH 先だけ差し替えて本番へ持っていく、という流れが現実的になった。
参考:
- DuckDB Iceberg Extension(公式ドキュメント): https://duckdb.org/docs/current/core_extensions/iceberg/overview
- DuckDB Iceberg REST Catalogs / Writing: https://duckdb.org/docs/current/core_extensions/iceberg/writing
- DuckDB リリース一覧(1.5.4 / 1.4.5 LTS): https://duckdb.org/news/