概要
Snowflake から Microsoft Fabric(Fabric)の OneLake 上に Delta テーブルを参照・クエリするまでの手順を整理します。
手順
1. Fabric のテナント設定を変更
管理ポータルにて サービス プリンシパルは Fabric の公開用 API を呼び出すことができます の設定を 有効化 にします。
2. Fabric にてワークスペースにレイクハウスを作成
対象ワークスペースにレイクハウスを作成します。
3. Fabric にてテーブルを作成
%%sql
CREATE OR REPLACE TABLE FABRIC_TABLE_01 (
ID INT,
NAME STRING,
TS TIMESTAMP_NTZ
);
%%sql
INSERT INTO FABRIC_TABLE_01 (ID, NAME, TS)
VALUES
(1, 'Alice', CURRENT_TIMESTAMP());
%%sql
SELECT * FROM FABRIC_TABLE_01;
4. テーブルの URL を取得
テーブルを右クリックし、プロパティを選択します。
URL の値を取得します。
上記で取得した URL にて、 httpsをazureに変更した上で、 VOLUME と TABLE にて指定する値に分けます。
https://onelake.dfs.fabric.microsoft.com/qiita_sf_with_fabric/snowflake.Lakehouse/Tables/dbo/fabric_table_01
↓
VOLUME に指定: azure://onelake.dfs.fabric.microsoft.com/qiita_sf_with_fabric/snowflake.Lakehouse/Tables
TABLE に指定: dbo/fabric_table_01
5. テナント ID を取得
Azure Entra ID(Azure AD)のテナント ID を取得します。
6. Snowflake にて Volume を作成
STORAGE_BASE_URL に取得した テーブルの URLの前半部分 を、AZURE_TENANT_ID に取得した テナント ID をセットして External Volume を作成します。
CREATE OR REPLACE EXTERNAL VOLUME onelake_delta_vol_01
STORAGE_LOCATIONS =
(
(
NAME = 'onelake delta volume'
STORAGE_PROVIDER = 'AZURE'
STORAGE_BASE_URL = 'azure://onelake.dfs.fabric.microsoft.com/qiita_sf_with_fabric/snowflake.Lakehouse/Tables'
AZURE_TENANT_ID = '02dd4e36-xxx'
)
)
ALLOW_WRITES = false;
ALLOW_WRITESをFALSEで指定している背景としては、Snowflake にて Iceberg テーブルのメタデータファイル作成を避けるためです。ALLOW_WRITESに関する動作について下記のドキュメントにて確認してください。
7. AZURE_CONSENT_URL にて認証情報をテナントに追加
External Volume の作成後、DESC EXTERNAL VOLUME の結果から AZURE_CONSENT_URL を取得します。
DESC EXTERNAL VOLUME onelake_delta_vol_01;
SELECT
PARSE_JSON($4):AZURE_MULTI_TENANT_APP_NAME::string AS AZURE_MULTI_TENANT_APP_NAME,
PARSE_JSON($4):AZURE_CONSENT_URL::string AS AZURE_CONSENT_URL
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
WHERE $2 = 'STORAGE_LOCATION_1';
AZURE_CONSENT_URL にアクセスし、Azure へログインしたうえで 承諾 を選択します。
8. Fabric にて Snowflake の認証情報に権限付与
Fabric 側(OneLake 側)で、Snowflake が利用するサービスプリンシパルにワークスペース権限を付与します。
ワークスペースにて、右上の アクセスの管理 を選択します。
+ユーザーまたはグループの追加 を選択します。
AZURE_MULTI_TENANT_APP_NAME のハイフン前までの名称(例:akjttesnowflakepacint_1768903577114 -> akjttesnowflakepacint)を追加し、共同作成者 を選択したうえで、追加 を選択します。
Snowflake にて External Volume の疎通確認を行い、success が true であることを確認します。
SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('onelake_delta_vol_01');
{
"success": true,
"storageLocationSelectionResult": "PASSED",
"storageLocationName": "onelake delta volume",
"servicePrincipalProperties": "AZURE_MULTI_TENANT_APP_NAME: akjttesnowflakepacint_1768903577114; AZURE_CONSENT_URL: https://login.microsoftonline.com/02dd4e36-5bc7-47b7-b351-1cf888365c24/oauth2/authorize?client_id=ece9bf25-a45d-4b53-b844-fc958a3b5dd0&response_type=code",
"location": "azure://onelake.dfs.fabric.microsoft.com/qiita_sf_with_fabric/snowflake.Lakehouse/Tables",
"storageAccount": "onelake",
"region": "southeastasia",
"writeResult": "UNVERIFIED because the external volume doesn't allow writes",
"readResult": "UNVERIFIED because the external volume doesn't allow writes",
"listResult": "UNVERIFIED because the external volume doesn't allow writes",
"deleteResult": "UNVERIFIED because the external volume doesn't allow writes",
"awsRoleArnValidationResult": "SKIPPED",
"azureGetUserDelegationKeyResult": "SKIPPED"
}
9. Snowflake にて Delta ベースの Iceberg テーブルを作成
データベースとスキーマを作成します。
CREATE DATABASE IF NOT EXISTS ONELAKE_ICEBERG_01;
CREATE SCHEMA IF NOT EXISTS ONELAKE_ICEBERG_01.SCHEMA_01;
USE DATABASE ONELAKE_ICEBERG_01;
USE SCHEMA SCHEMA_01;
Delta のカタログ統合を作成します。
CREATE OR REPLACE CATALOG INTEGRATION FABRIC_DELTA_CATALOG_INTEGRATION
CATALOG_SOURCE = OBJECT_STORE
TABLE_FORMAT = DELTA
ENABLED = TRUE;
テーブルを作成し、データを取得できることを確認します。BASE_LOCATIONには、 テーブルの URLの後半部分を指定しています。
CREATE OR REPLACE ICEBERG TABLE FABRIC_TABLE_01
CATALOG = FABRIC_DELTA_CATALOG_INTEGRATION
EXTERNAL_VOLUME = onelake_delta_vol_01
BASE_LOCATION = 'dbo/fabric_table_01'
AUTO_REFRESH = TRUE;
SELECT * FROM FABRIC_TABLE_01;
10. Fabric にてデータを追加
Fabirc にてテーブルにデータを追加します。
%%sql
INSERT INTO FABRIC_TABLE_01 (ID, NAME, TS)
VALUES
(2, 'Bob', CURRENT_TIMESTAMP());
Snowflake にてデータを追加されていることを確認します。
SELECT * FROM FABRIC_TABLE_01;
Snowflake 側でデータが自動で更新されている要因は、テーブル作成時にAUTO_REFRESHをTRUEにしたためです。手動で実施したい場合には、AUTO_REFRESHがTRUEの場合にはエラーとなるため、FALSEにする必要があります。
ALTER ICEBERG TABLE FABRIC_TABLE_01 REFRESH;
SQL Compilation error: Manual Refresh is not supported for Iceberg Tables with Auto Refresh enabled. To continue, please disable Auto Refresh for table 'FABRIC_TABLE_01'.
ALTER ICEBERG TABLE FABRIC_TABLE_01 SET AUTO_REFRESH = FALSE;
ALTER ICEBERG TABLE FABRIC_TABLE_01 REFRESH;
<補足> Snowflake にて Fabric にてメタデータ仮想化した Delta 化したテーブルの参照
下記記事の手順にて作成した Snowflake マネージド Iceberg テーブルを OneLake 上で Delta テーブル化したのですが、そのテーブルを参照することが可能です。
Snowflake にて Delta テーブル化したテーブルを参照した Delta ベースの Iceberg テーブルを作成し、クエリを実行できることを確認します。
CREATE OR REPLACE ICEBERG TABLE SNOWFLAKE_TO_FABRIC_DELTA_TABLE_01
CATALOG = FABRIC_DELTA_CATALOG_INTEGRATION
EXTERNAL_VOLUME = onelake_delta_vol_01
BASE_LOCATION = 'dbo/TABLE_01.gGv9twFu'
AUTO_REFRESH = TRUE;
SELECT * FROM SNOWFLAKE_TO_FABRIC_DELTA_TABLE_01;
Snowflake にて Iceberg テーブルにデータを挿入します。
INSERT INTO TABLE_01 (ID, NAME, TS)
VALUES
(3, 'Cathy', CURRENT_TIMESTAMP());
Delta テーブル化したテーブルを参照した Delta ベースの Iceberg テーブルをクエリし、データが追加されていることを確認します。
SELECT * FROM SNOWFLAKE_TO_FABRIC_DELTA_TABLE_01;























