
Databricks 管理の Iceberg テーブルに対する Snowflake からの読み書きを試してみる
はじめに
Snowflake から Databricks 管理の Iceberg テーブルの読み書きを試してみた内容を記事としました。
各製品の Iceberg 対応の概要
Snowflake の Iceberg 対応
Snowflake はオープンテーブルフォーマットである Apache Iceberg に対応しています。Snowflake 管理の Iceberg テーブルの他、Apache Iceberg REST OpenAPI 仕様に準拠した外部カタログが管理する Iceberg テーブルへのアクセス(読み取り・書き込み)も可能です。
この際、Snowflake ではカタログ統合を通じて外部カタログサーバーとの接続を設定します。OAuth・Bearer トークン・SigV4 など複数の認証方式に対応しており、サポートするカタログにも Snowflake Open Catalog、AWS Glue、Unity Catalog などが挙げられています。
Databricks Unity Catalog の Iceberg 対応
Databricks の Unity Catalog は、Delta Lake と Apache Iceberg の両形式に対応した Managed テーブルをサポートしています。テーブル作成時に USING ICEBERG を指定することで Iceberg テーブルを作成でき、Iceberg REST Catalog API を提供しているため、Iceberg クライアントからの読み書きアクセスが可能です。
これらを組み合わせることで、Unity Catalog の Iceberg REST API をエンドポイントとして、Snowflake のカタログ統合から Databricks 管理の Iceberg テーブルに対して読み書きできます。
前提条件
以下の環境を使用しています。
- Databricks:Free Edition
- Snowflake:トライアルアカウント
Databricks 側
前提としてメタストアへの外部アクセスを有効化しておきます。
また、ここではカタログ作成時に MANAGED LOCATION を指定することで、指定の S3 配下をデータファイルの保存先としました。
そのため、事前に S3 を使用する外部ロケーションの作成を行います。こちらの手順は以下に記載があります。
同様の内容を以下の記事でも設定しているため、詳細はこちらをご参照ください。
Iceberg テーブルの作成
外部ロケーションを作成後、こちらを指定するカタログ、スキーマ、Iceberg テーブルを作成します。
-- カタログ作成時に外部ロケーションを指定
CREATE CATALOG yasuhara_iceberg_catalog
MANAGED LOCATION 's3://<bucket>/dbx-catalog-root/';
-- スキーマを作成
CREATE SCHEMA IF NOT EXISTS yasuhara_iceberg_catalog.my_schema;
-- Managed Iceberg テーブルを作成
CREATE TABLE yasuhara_iceberg_catalog.my_schema.orders (
order_id BIGINT,
customer_id BIGINT,
order_ts TIMESTAMP,
total_amt DECIMAL(12, 2)
)
USING ICEBERG;
-- レコードを追加
INSERT INTO yasuhara_iceberg_catalog.my_schema.orders
(order_id, customer_id, order_ts, total_amt)
VALUES
(1, 12345, '2025-03-23 10:00:00', 9800.00),
(2, 22222, '2025-03-23 11:00:00', 15000.00),
(3, 33333, '2025-03-23 12:00:00', 3500.00);
-- 参照
SELECT * FROM yasuhara_iceberg_catalog.my_schema.orders;
サービスプリンシパルの追加
Snowflake からのアクセスに使用するサービスプリンシパルを Databricks に追加します。

続けて、OAuth 認証で使用するクライアントシークレットを生成します。Snowflake のカタログ統合では TYPE = OAUTH を使用することで OAuth での認証が可能です。

生成されたクライアント ID・シークレットは後の権限設定、Snowflake 側の設定(OAUTH_CLIENT_ID / OAUTH_CLIENT_SECRET)で使用するため、控えておきます。
次に、Snowflake 用サービスプリンシパルに必要な権限を付与します。
GRANT EXTERNAL USE SCHEMA ON SCHEMA yasuhara_iceberg_catalog.my_schema
TO `<アプリケーションID>`;
GRANT USE CATALOG ON CATALOG yasuhara_iceberg_catalog TO `<アプリケーションID>`;
GRANT USE SCHEMA ON CATALOG yasuhara_iceberg_catalog TO `<アプリケーションID>`;
GRANT SELECT ON SCHEMA yasuhara_iceberg_catalog.my_schema TO `<アプリケーションID>`;
Databricks 側の作業は以上です。
Snowflake側
カタログ統合の作成
Snowflake から Databricks Unity Catalog の Iceberg REST API に接続するためのカタログ統合を作成します。
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE CATALOG INTEGRATION dbx_unity_catalog
CATALOG_SOURCE = ICEBERG_REST
TABLE_FORMAT = ICEBERG
REST_CONFIG = (
CATALOG_URI = 'https://<ワークスペース>.cloud.databricks.com/api/2.1/unity-catalog/iceberg-rest'
CATALOG_NAME = 'yasuhara_iceberg_catalog'
ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS -- 認証情報を UC から委譲
)
REST_AUTHENTICATION = (
TYPE = OAUTH
OAUTH_TOKEN_URI = 'https://<ワークスペース>.cloud.databricks.com/oidc/v1/token'
OAUTH_CLIENT_ID = '<クライアントID>'
OAUTH_CLIENT_SECRET = '<シークレット>'
OAUTH_ALLOWED_SCOPES = ('all-apis')
)
ENABLED = TRUE;
-- Catalog-Linked Database を作成(Unity Catalog 内のテーブルが自動検出される)
CREATE DATABASE databricks_iceberg_db
LINKED_CATALOG = (
CATALOG = 'dbx_unity_catalog'
);
ポイントとして、ACCESS_DELEGATION_MODE = VENDED_CREDENTIALS を指定することで、Snowflake がストレージへアクセスする際の認証情報を Unity Catalog 側から動的に取得(委譲)します。これにより、外部ボリュームの設定を不要とでき、アクセス制御・認証情報の管理を Unity Catalog 側に一元化できます。
カタログ統合の作成後、統合オブジェクトの接続状態を確認します。特にエラーが出ていなければ問題ないです。
SELECT SYSTEM$VERIFY_CATALOG_INTEGRATION('DBX_UNITY_CATALOG');
Databricks 管理の Iceberg のテーブルの読み取り
カタログリンクデータベースを作成すると、Unity Catalog 内のテーブルが Snowflake 側に自動的に同期されます。同期後にテーブルの存在を確認し、クエリを実行してみます。
-- テーブルを確認
SHOW TABLES IN DATABASE databricks_iceberg_db;
--クエリ実行
SELECT * FROM databricks_iceberg_db.my_schema.orders;

Databricks 側のデータが Snowflake からデータのコピーなしに参照できることを確認できました。
Databricks 管理の Iceberg のテーブルへの書き込み
続けて、SnowflakeからDatabricks管理のIcebergテーブルへの書き込みを試してみます。
事前に Databricks 側で書き込み権限を付与します。
-- 書き込み権限
GRANT MODIFY ON SCHEMA yasuhara_iceberg_catalog.my_schema
TO `<アプリケーションID>`;
その後、Snowflake 側からレコードを追加します。
INSERT INTO databricks_iceberg_db.my_schema.orders
(order_id, customer_id, order_ts, total_amt)
VALUES
(4, 12346, '2025-03-23 12:00:00', 1200.00);
Snowflake側でINSERT後のレコードを確認します。
SELECT * FROM databricks_iceberg_db.my_schema.orders;

Databricks側でも同じデータを確認します。
SELECT * FROM yasuhara_iceberg_catalog.my_schema.orders;

Snowflake から INSERT したレコードが Databricks 側にも反映されていることを確認できました。
Snowflake から Databricks 管理の Iceberg テーブルを追加
続けて、Snowflake 側から Databricks 管理の Iceberg テーブル自体を新規作成できるかも確認してみます。
事前に対象スキーマに対してテーブル作成権限を Databricks 側で付与します。
GRANT CREATE TABLE ON SCHEMA yasuhara_iceberg_catalog.my_schema
TO `<アプリケーションID>`;
その後、Snowflake 側のカタログリンクデータベースを通して Iceberg テーブルを作成します。
CREATE ICEBERG TABLE databricks_iceberg_db.my_schema.orders_from_snowflake (
order_id INT,
customer_id INT,
order_ts TIMESTAMP,
total_amt NUMBER(12, 2)
);
INSERT INTO databricks_iceberg_db.my_schema.orders_from_snowflake
(order_id, customer_id, order_ts, total_amt)
VALUES
(101, 50001, '2025-03-23 13:00:00', 5000.00),
(102, 50002, '2025-03-23 14:00:00', 7200.00);

Snowflake 側で新しいテーブルが作成されたことを確認できました。次に Databricks 側からも参照できるかを確認します。
※Snowflake から新規作成したテーブルは、Databricks 側で確認に使うユーザーに自動で SELECT が付与されない場合があります。そのため、必要に応じて Databricks 側の確認ユーザーまたはグループに参照権限を追加で付与します。
権限付与後、Databricks から参照すると Snowflake 側で作成したテーブルとレコードを確認できました。


さいごに
Snowflake から Databricks 管理の Iceberg テーブルに対する読み書きを試してみました。
こちらの内容がどなたかの参考になれば幸いです。








