Snowflake Horizonカタログを介した外部エンジンを使用して Apache Iceberg™ テーブルにクエリする

Snowflake Horizonカタログを介する外部クエリエンジンを使用して、Snowflake管理の Apache Iceberg™ テーブルをクエリします。外部エンジンとこの相互運用性を確保するために、 Apache Polaris™(インキュベート中) は Horizonカタログに統合されています。さらに、Horizonカタログは Apache Iceberg™ REST API (Horizon Iceberg REST カタログ API )を公開します。この API により、外部クエリエンジンを使用してテーブルを読み取ることができます。

外部クエリエンジンでSnowflake管理のIcebergテーブルをクエリするには、 Snowflake管理IcebergテーブルとSnowflake Open Catalogを同期する 代わりにこの機能を使用できます。Open Catalogの詳細については、 Snowflake Open Catalogの概要 をご参照ください。

Horizonカタログを介して外部クエリエンジンをIcebergテーブルに接続することで、次のタスクを実行できます。

  • オープンIceberg REST プロトコルをサポートする外部クエリエンジンを使用して、Apache Spark™など、これらのテーブルをクエリします。

  • 単一のHorizonカタログエンドポイントを使用して、新規または既存のSnowflakeアカウント内の既存および新規のSnowflake管理のIcebergテーブルをクエリします。

  • Snowflakeの既存のユーザー、ロール、ポリシー、および認証を使用してテーブルをクエリします。

  • ベンディングされた認証情報を使用します。

Snowflake Horizonカタログの詳細については、 Snowflake Horizon カタログ をご参照ください。

次の図は、Horizonカタログを介してSnowflake管理のIcebergテーブルを読み取り、これらのテーブルに対してSnowflakeが読み書きを行う外部クエリエンジンを示しています。

Horizonカタログを介してSnowflake管理のIcebergテーブルを読み取り、これらのテーブルに対してSnowflakeが読み書きを行う外部クエリエンジンを示す図。

請求

  • Horizon Iceberg REST カタログ API はすべてのSnowflakeエディションで利用可能です。

  • その API リクエストは100万件のコールごとに0.5クレジットとして請求され、クラウドサービスとして課金されます。

  • クロスリージョンデータアクセスの場合、 Snowflakeサービス利用表 に記載されている標準のクロスリージョンデータエグレス料金が適用されます。

注釈

この機能の請求開始は2026年半ばです。変更される可能性があります。

サポートされる外部エンジンとカタログ

以下の表は、すべてを網羅しているわけではありませんが、Horizon Iceberg REST カタログ API と統合する多くの外部エンジンとカタログを示しています。この統合により、外部システムからSnowflakeが管理するIcebergテーブルにアクセスできるようになります。

サポートされている外部エンジン

次の外部クエリエンジンは、Horizon Iceberg REST カタログ API と統合されます。

製品

Horizonカタログを介してSnowflakeが管理するIcebergテーブルにアクセスする

Apache Doris™

Apache Flink™

Apache Spark™

Dremio

DuckDB

PyIceberg

StarRocks

Trino

サポートされる外部カタログ

次の外部カタログは、Horizon Iceberg REST カタログ API と統合されます。

製品

Horizonカタログを介してSnowflakeが管理するIcebergテーブルにアクセスする

コメント

Apache Polaris™

AWS Glue

この統合の構成方法については、 AWS Big Data Blog内の AWS Glueデータカタログでカタログフェデレーションを使用してSnowflake Horizonカタログデータにアクセスする をご参照ください。

Palantir Foundry

この統合の構成方法については、Palantirドキュメント内の Icebergテーブル(仮想テーブルのみ) をご参照ください。

Databricks Unityカタログ

発表されていません

Google BigLake Metastore

開発中

Microsoft Fabric / Synapse

開発中

前提条件

クエリするIcebergテーブルを含むSnowflakeアカウントのアカウント識別子を取得します。手順については、 アカウント識別子 をご参照ください。次の場合にこの識別子を指定します。Icebergテーブルに外部クエリエンジンを接続する

Tip

SQL を使用してアカウント識別子を取得するには次のコマンドを実行できます。

SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME();
Copy

(オプション)プライベート接続

安全な接続のために、Horizon カタログエンドポイントにアクセスする際の、Snowflakeアカウント用 :doc:` インバウンド </user-guide/private-connectivity-inbound>` および :doc:` アウトバウンド </user-guide/private-connectivity-outbound>` プライベート接続の構成を検討してください。

注釈

プライベート接続は、Amazon S3またはAzure Storage(ADLS)に保存されているSnowflake管理のIcebergテーブル用としてのみサポートされます。

外部クエリエンジンを使用してIcebergテーブルをクエリするワークフロー

外部クエリエンジンを使用してIcebergテーブルをクエリするには、以下のステップを完了します:

  1. Icebergテーブルを作成する

  2. アクセス制御を構成する

  3. 認証用アクセストークンを取得する

  4. アクセストークンの権限を確認する

  5. (オプション)データ保護ポリシーを構成する

  6. Horizonカタログを介する外部クエリエンジンとIcebergテーブルを接続する

  7. Icebergテーブルをクエリする

ステップ1:Icebergテーブルの作成

重要

クエリするSnowflake管理のIcebergテーブルがすでにある場合は、このステップをスキップできます。

このステップでは、Snowflakeをカタログとして使用するSnowflake管理のIcebergテーブルを作成し、外部クエリエンジンでクエリを実行できるようにします。手順については、以下のトピックをご参照ください。

ステップ2:アクセス制御の構成

重要

クエリするIcebergテーブルへのアクセスで構成されたロールがすでにある場合は、このステップをスキップできます。

このステップでは、外部クエリエンジンでクエリを実行するSnowflake管理のIcebergテーブルのアクセス制御を構成します。たとえば、Snowflakeでは次のロールを設定できます:

  • data_engineerロール。データベース内のすべてのスキーマとSnowflake管理のすべてのIcebergテーブルにアクセスできます。

  • data_analyst role ロール。データベース内の1つのスキーマにアクセスし、そのスキーマ内の2つのSnowflake管理のIcebergテーブルにのみアクセスできます。

Icebergテーブルへのアクセスを構成する

Icebergテーブルにクエリを実行するには、操作の実行に使用されるロールに、外部クラウドストレージへの接続に使用する外部ボリュームに対するUSAGE権限が必要です。

次の例では、``my_ext_vol``という名前の外部ボリュームのUSAGE権限を、``data_engineer``という名前のロールに付与します。

GRANT USAGE ON EXTERNAL VOLUME my_ext_vol TO ROLE data_engineer;
Copy

外部ボリュームのUSAGE権限について詳しくは、:ref:`label-external_volume_privileges`を参照してください。

注釈

Icebergテーブルにクエリを実行するには、操作を実行するために使用されるロールに、Icebergテーブルに対するSELECT権限、および親データベースとスキーマに対するUSAGE権限およびMONITOR権限も必要です。これらの権限をロールに付与する例については、:ref:`label-tables_iceberg_query_using_external_query_engine_snowflake_horizon_set_up_service_account_user`を参照してください。

例:サービスアカウントユーザーの設定

次の例では、Icebergテーブルへの読み取り専用アクセスを持つSnowflakeのサービスアカウントユーザーを設定します。

  • ``data_engineer``ロールを作成します。

  • ``my_ext_vol``外部ボリュームに対するUSAGE権限を``data_engineer``ロールに付与します。

  • ``iceberg_test_db``データベースとその``public``スキーマに対するUSAGE権限およびMONITOR権限を``data_engineer``ロールに付与します。

  • ``test_table``Icebergテーブルに対するSELECT権限を付与します。

  • ``horizon_rest_srv_account_user``という名前のサービスユーザーを作成し、そのユーザーに``data_engineer``ロールを割り当てます。

CREATE OR REPLACE ROLE data_engineer;

GRANT USAGE ON EXTERNAL VOLUME my_ext_vol TO ROLE data_engineer;

GRANT USAGE,MONITOR ON DATABASE iceberg_test_db TO ROLE data_engineer;
GRANT USAGE,MONITOR ON SCHEMA iceberg_test_db.public TO ROLE data_engineer;

GRANT SELECT ON TABLE iceberg_test_db.public.test_table TO ROLE data_engineer;

CREATE OR REPLACE USER horizon_rest_srv_account_user TYPE=SERVICE DEFAULT_ROLE=data_engineer;

GRANT ROLE data_engineer TO USER horizon_rest_srv_account_user;
Copy

(オプション)IcebergテーブルにFUTURE GRANTを適用する

スキーマで作成された新しいIcebergテーブルへのアクセスを保証するには、:ref:`GRANT … ON FUTURE ICEBERG TABLES <label-grant_privilege_schema_future_grants>`構文を使用します。

次の例では、``my_schema``という名前のスキーマで作成されたIcebergテーブルへのアクセス権を``data_engineer``ロールに付与します。

GRANT SELECT, REFERENCES ON FUTURE ICEBERG TABLES IN SCHEMA my_db.my_schema TO ROLE data_engineer;
Copy

Snowflakeでのアクセス制御について詳しくは、次のトピックを参照してください。

ステップ3:認証用アクセストークンの取得

このステップでは、SnowflakeアカウントのHorizonカタログエンドポイントを認証するために必要なアクセストークンを取得します。各ユーザー(サービスまたは人間)用のアクセストークンと、Snowflake管理のIcebergテーブルへのアクセスで構成されたロールを取得する必要があります。たとえば、DATA_ENGINEER ロールを持つユーザーと DATA_ANALYST ロールを持つ別のユーザーに対して、1つのアクセストークンを取得する必要があります。

Horizon Catalogを介して外部クエリエンジンをIcebergテーブルに接続する ときに、このアクセストークンを指定します。

次の認証オプションのいずれかを使用して、アクセストークンを取得できます。

外部 OAuth

外部 OAuth を使用している場合は、IDプロバイダーのアクセストークンを生成します。手順については、 外部 OAuth の概要 をご参照ください。

注釈

外部 OAuth の場合は、アクセストークンを指定する代わりに、自動トークン更新を使用してエンジンへの接続を構成することもできます。

キーペア認証

キーペア認証を使用してアクセストークンを取得する場合は、プライベートキーで JSON ウェブトークン(JWT)に署名します。

次のステップでは、キーペア認証用のアクセストークンを生成する方法を説明します。

  1. キーペア認証を構成する

  2. ユーザーにロールを付与する

  3. JSON ウェブトークンを生成する( JWT )

  4. アクセストークンを生成する

ステップ1:キーペア認証を構成する

このステップでは、次のタスクを実行します。

  • 秘密キーを生成する

  • 公開キーを生成する

  • 秘密キーと公開キーを安全に保管する

  • Snowflakeユーザーに公開キーを割り当てる権限を付与します。

  • Snowflakeユーザーに公開キーを割り当てる

  • ユーザーの公開キーのフィンガープリントを検証する

手順については、 キーペア認証の構成 をご参照ください。

ステップ2:ユーザーにロールを付与する

GRANT ROLE コマンドを実行して、クエリするテーブルに対する権限を持つSnowflakeロールをキーペア認証ユーザーに付与します。たとえば、 my_service_user ユーザーに ENGINEER ロールを付与するには、次のコマンドを実行します。

GRANT ROLE ENGINEER to user my_service_user;
Copy

ステップ3:JSON ウェブトークン( JWT )を生成する

このステップでは、 SnowSQL を使用してキーペア認証用の JSON ウェブトークン( JWT )を生成します。

注釈

SnowSQL を使用して JWT を生成する:

snowsql --private-key-path "<private_key_file>" \
  --generate-jwt \
  -h "<account_identifier>.snowflakecomputing.com" \
  -a "<account_locator>" \
  -u "<user_name>"
Copy

条件:

  • <private_key_file> is the path to your private key file that corresponds to the public key assigned to your Snowflake user.For example: /Users/jsmith/.ssh/rsa_key.p8.

  • <account_identifier>``はSnowflakeアカウントのアカウント識別子であり、形式は``<organization_name>-<account_name>``です。アカウント識別子を見つけるには、 :ref:`label-tables_iceberg_query_using_external_query_engine_snowflake_horizon_before_you_begin` をご参照ください。アカウント識別子の例: ``myorg-myaccount

  • <account_locator> は、Snowflakeアカウントのアカウントロケーターです。

    アカウントロケーターを見つけるには、 SnowsightでSnowflakeアカウント情報を見つける を参照し、 Account Details ダイアログで Account locator を確認します。

  • <user_name> は、ユーザーに公開キーが割り当てられたSnowflakeユーザーのユーザー名です。

ステップ4: アクセストークンを生成する

重要

アクセストークンを生成するには、まず JWT を生成する 必要があります。まず JWT を生成する必要があるのは、アクセストークンを生成するのに JWT を使用するためです。

curl コマンドを使用してアクセストークンを生成します。

curl -i --fail -X POST "https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog/v1/oauth/tokens" \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --data-urlencode 'grant_type=client_credentials' \
 --data-urlencode 'scope=session:role:<role>' \
 --data-urlencode 'client_secret=<JWT_token>'
Copy

条件:

  • <account_identifier>``はSnowflakeアカウントのアカウント識別子であり、形式は``<organization_name>-<account_name>``です。アカウント識別子を見つけるには、 :ref:`label-tables_iceberg_query_using_external_query_engine_snowflake_horizon_before_you_begin` をご参照ください。アカウント識別子の例: ``myorg-myaccount

  • ``<role>``は、ENGINEERなど、Icebergテーブルへのアクセスを付与されたSnowflakeロールです。

  • <JWT_token> は、前のステップで生成した JWT です。

プログラムアクセストークン(PAT)

PATs を使用する場合は、認証用の PAT を生成します。

まず、 Icebergテーブルに外部クエリエンジンを接続する ために使用する PAT を生成します。次に、アクセストークンを生成します。これは、 PAT の権限を確認するためにのみ使用します。

ステップ1:PAT を生成する

PAT の構成および生成方法の手順については、 認証のためのプログラム アクセス トークンの使用 をご参照ください。

次の例では、 ALTER USER ... ADD PROGRAMMATIC ACCESS TOKEN (PAT) コマンドを使用して、前のステップで作成したサービスアカウントユーザー用のプログラムアクセストークン( PAT )を作成します。

ALTER USER IF EXISTS HORIZON_REST_SRV_ACCOUNT_USER
ADD PAT HORIZON_REST_SRV_ACCOUNT_USER_PAT
  DAYS_TO_EXPIRY = 7
  ROLE_RESTRICTION = 'DATA_ENGINEER'
  COMMENT = 'HORIZON REST API PAT FOR SERVICE ACCOUNT';
Copy

ステップ2: PAT のアクセストークンを生成する

このステップでは、 PAT のアクセストークンを生成します。

注意

PAT の 権限を確認する 場合にのみ、このステップで生成するアクセストークンを指定します。Icebergテーブルに外部クエリエンジンを接続する 場合は、このステップで生成するアクセストークンではなく、前のステップで生成した PAT を指定する必要があります。

curl コマンドを使用して、 PAT のアクセストークンを生成します。

curl -i --fail -X POST "https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog/v1/oauth/tokens" \
 --header 'Content-Type: application/x-www-form-urlencoded' \
 --data-urlencode 'grant_type=client_credentials' \
 --data-urlencode 'scope=session:role:<role>' \
 --data-urlencode 'client_secret=<PAT_token>'
Copy

条件:

  • <account_identifier>``はSnowflakeアカウントのアカウント識別子であり、形式は``<organization_name>-<account_name>``です。アカウント識別子を見つけるには、 :ref:`label-tables_iceberg_query_using_external_query_engine_snowflake_horizon_before_you_begin` をご参照ください。アカウント識別子の例: ``myorg-myaccount

  • ``<role>``はPATに付与されるSnowflakeロールであり、ENGINEERなど、クエリするIcebergテーブルへのアクセス権を持っています。

  • <PAT_token> は、前のステップで生成した PAT トークンの値です。

ステップ4: アクセストークンの権限を確認する

このステップでは、前のステップで取得したアクセストークンの権限を確認します。

Horizon IRC エンドポイントへのアクセスを確認する

curl コマンドを使用して、Horizon IRC エンドポイントへのアクセス権限があることを確認します。

curl -i --fail -X GET "https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog/v1/config?warehouse=<database_name>" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json"
Copy

条件:

  • <account_identifier>``はSnowflakeアカウントのアカウント識別子であり、形式は``<organization_name>-<account_name>``です。アカウント識別子を見つけるには、 :ref:`label-tables_iceberg_query_using_external_query_engine_snowflake_horizon_before_you_begin` をご参照ください。アカウント識別子の例: ``myorg-myaccount

  • ``<access_token>``は、生成したアクセストークンです。PAT を使用している場合、この値は 生成したアクセストークン であり、生成した 個人用アクセストークン( PAT ) ではありません。

  • <database_name> は、クエリするデータベースの名前です。

    重要

    小文字で作成された場合でも、データベース名は すべて大文字 で指定する必要があります。

戻り値の例:

{
  "defaults": {
    "default-base-location": ""
  },
  "overrides": {
    "prefix": "MY-DATABASE"
  }
}

テーブルのメタデータを取得する

GET リクエストを作成してテーブルのメタデータを取得することもできます。Snowflakeは loadTable 操作を使用して、 REST カタログからテーブルメタデータをロードします。

curl -i --fail -X GET "https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog/v1/<database_name>/namespaces/<namespace_name>/tables/<table_name>" \
 -H "Authorization: Bearer <access_token>" \
 -H "Content-Type: application/json"
Copy

条件:

  • <account_identifier>``はSnowflakeアカウントのアカウント識別子であり、形式は``<organization_name>-<account_name>``です。アカウント識別子を見つけるには、 :ref:`label-tables_iceberg_query_using_external_query_engine_snowflake_horizon_before_you_begin` をご参照ください。アカウント識別子の例: ``myorg-myaccount

  • <database_name> は、取得するメタデータのテーブルのデータベースです。

  • <namespace_name> は、取得するメタデータのテーブルの名前空間です。

  • <table_name> は、取得するメタデータのテーブルです。

  • ``<access_token>``は、生成したアクセストークンです。PAT を使用している場合、この値は 生成したアクセストークン であり、生成した 個人用アクセストークン( PAT ) ではありません。

重要

オブジェクトが小文字で作成された場合でも、データベース名、名前空間、およびテーブル名を すべて大文字 で指定する必要があります。

(任意)ステップ5:データ保護ポリシーを構成する

このステップでは、Icebergテーブルのデータ保護ポリシーを構成します。Snowflakeデータポリシーで保護する必要があるテーブルがない場合は、次のステップに進むことができます。

注釈

データ保護ポリシーで保護されたテーブルは、Horizon Iceberg RESTAPI 経由およびApache Spark™を使用してアクセスできます。

データ保護ポリシーの構成方法については、 Horizon Iceberg RESTAPI 経由およびApache Spark™を使用してアクセスされるIcebergテーブルのデータ保護ポリシーを構成する をご参照ください。

ステップ6:Horizonカタログを介する外部クエリエンジンとIcebergテーブルの接続

このステップでは、Horizonカタログを介して外部クエリエンジンをIcebergテーブルに接続します。この接続により、外部クエリエンジンを使用してテーブルをクエリすることができます。

外部エンジンはSnowflakeによって公開される Apache Iceberg™ REST エンドポイントを使用します。Snowflakeアカウントの場合、このエンドポイントは次の形式をとります。

https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog
Copy

このステップのコード例は、Sparkで接続を設定する方法を示しています。コード例は PySpark です。詳細は以下のセクションをご覧ください。

外部 OAuth またはキーペア認証を使用した接続

次の構成のいずれかを使用して接続します。

データポリシーを適用せずに外部クエリエンジンを接続する

  • 外部 OAuth またはキーペア認証を使用して、外部クエリエンジンをIcebergテーブルに接続するには、次のコード例を使用します。

このコードはデータ保護ポリシーを適用しません。

# Snowflake Horizon Catalog Configuration, change as per your environment

CATALOG_URI = "https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog"
HORIZON_SESSION_ROLE = f"session:role:<role>"
CATALOG_NAME = "<database_name>" #provide in UPPER CASE

# Cloud Service Provider Region Configuration (where the Iceberg data is stored)
REGION = "eastus2"

# Paste the External Oauth Access token that you generated in Snowflake here
ACCESS_TOKEN = "<your_access_token>"

# Iceberg Version
ICEBERG_VERSION = "1.9.1"

def create_spark_session():
  """Create and configure Spark session for Snowflake Iceberg access."""
  spark = (
      SparkSession.builder
      .appName("SnowflakeIcebergReader")
      .master("local[*]")

# JAR Dependencies for Iceberg and Azure
      .config(
          "spark.jars.packages",
          f"org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:{ICEBERG_VERSION},"
          f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"
          # for Azure storage, use the below package and comment above azure bundle
          # f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"
      )

      # Iceberg SQL Extensions
      .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions")
      .config("spark.sql.defaultCatalog", CATALOG_NAME)

      # Horizon REST Catalog Configuration
      .config(f"spark.sql.catalog.{CATALOG_NAME}", "org.apache.iceberg.spark.SparkCatalog")
      .config(f"spark.sql.catalog.{CATALOG_NAME}.type", "rest")
      .config(f"spark.sql.catalog.{CATALOG_NAME}.uri", CATALOG_URI)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.warehouse", CATALOG_NAME)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.token", ACCESS_TOKEN)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.scope", HORIZON_SESSION_ROLE)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.client.region", REGION)

      # Required for vended credentials
      .config(f"spark.sql.catalog.{CATALOG_NAME}.header.X-Iceberg-Access-Delegation", "vended-credentials")
      .config("spark.sql.iceberg.vectorization.enabled", "false")
      .getOrCreate()
  )
  spark.sparkContext.setLogLevel("ERROR")
  return spark
Copy

条件:

  • <account_identifier> は、クエリするIcebergテーブルを含むSnowflakeアカウントのSnowflakeアカウント識別子です。この識別子を見つけるには、 サポートされる外部エンジンとカタログ をご参照ください。

  • <your_access_token> は、取得したアクセストークンです。取得するには、 ステップ3:認証用アクセストークンの取得 をご参照ください。

    注釈

    外部 OAuth の場合は、アクセストークンを指定する代わりに、自動トークン更新を使用してエンジンへの接続を構成することもできます。

  • <database_name> は、クエリするSnowflake管理のIcebergテーブルを含むSnowflakeアカウントのデータベースの名前です。

    注釈

    Sparkの .warehouse プロパティは、Snowflakeウェアハウス名ではなく、Snowflake データベース 名を想定しています。

  • <role> は、クエリするIcebergテーブルへのアクセスで構成されたSnowflakeのロールです。例: DATA_ENGINEER。

重要

デフォルトでは、コード例はAmazon S3に保存された Apache Iceberg™ テーブル用に設定されています。IcebergテーブルがAzure Storage(ADLS)に保存されている場合は、次のステップを実行します:

  1. 次の行をコメントアウトします: f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"

  2. 次の行のコメントを解除します: # f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"

データポリシーが適用された外部クエリエンジンを接続する

プログラムのアクセストークン(PAT)を使用した接続

次の構成のいずれかを使用して接続します。

データポリシーを適用せずに外部クエリエンジンを接続する

  • 次のコード例を使用し、プログラムのアクセストークン(PAT)を使用して外部クエリエンジンをIcebergテーブルに接続します:

このコードはデータ保護ポリシーを適用しません。

# Snowflake Horizon Catalog Configuration, change as per your environment

CATALOG_URI = "https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog"
HORIZON_SESSION_ROLE = f"session:role:<role>"
CATALOG_NAME = "<database_name>" #provide in UPPER CASE

# Cloud Service Provider Region Configuration (where the Iceberg data is stored)
REGION = "eastus2"

# Paste the PAT you generated in Snowflake here
PAT_TOKEN = "<your_PAT_token>"

# Iceberg Version
ICEBERG_VERSION = "1.9.1"

def create_spark_session():
  """Create and configure Spark session for Snowflake Iceberg access."""
  spark = (
      SparkSession.builder
      .appName("SnowflakeIcebergReader")
      .master("local[*]")

# JAR Dependencies for Iceberg and Azure
      .config(
          "spark.jars.packages",
          f"org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:{ICEBERG_VERSION},"
          f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"
          # for Azure storage, use the below package and comment above azure bundle
          # f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"
      )

      # Iceberg SQL Extensions
      .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions")
      .config("spark.sql.defaultCatalog", CATALOG_NAME)

      # Horizon REST Catalog Configuration
      .config(f"spark.sql.catalog.{CATALOG_NAME}", "org.apache.iceberg.spark.SparkCatalog")
      .config(f"spark.sql.catalog.{CATALOG_NAME}.type", "rest")
      .config(f"spark.sql.catalog.{CATALOG_NAME}.uri", CATALOG_URI)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.warehouse", CATALOG_NAME)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.credential", PAT_TOKEN)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.scope", HORIZON_SESSION_ROLE)
      .config(f"spark.sql.catalog.{CATALOG_NAME}.client.region", REGION)

      # Required for vended credentials
      .config(f"spark.sql.catalog.{CATALOG_NAME}.header.X-Iceberg-Access-Delegation", "vended-credentials")
      .config("spark.sql.iceberg.vectorization.enabled", "false")
      .getOrCreate()
  )
  spark.sparkContext.setLogLevel("ERROR")
  return spark
Copy

条件:

  • <account_identifier> は、クエリするIcebergテーブルを含むSnowflakeアカウントのSnowflakeアカウント識別子です。この識別子を見つけるには、 サポートされる外部エンジンとカタログ をご参照ください。

  • <your_PAT_token> は取得した PAT です。取得するには、 ステップ3:認証用アクセストークンの取得 をご参照ください。

  • <role> は、クエリするIcebergテーブルへのアクセスで構成されたSnowflakeのロールです。例: DATA_ENGINEER。

  • <database_name> は、クエリするSnowflake管理のIcebergテーブルを含むSnowflakeアカウントのデータベースの名前です。

    注釈

    Sparkの .warehouse プロパティは、Snowflakeウェアハウス名ではなく、Snowflake データベース 名を想定しています。

重要

デフォルトでは、コード例はAmazon S3に保存された Apache Iceberg™ テーブル用に設定されています。IcebergテーブルがAzure Storage(ADLS)に保存されている場合は、次のステップを実行します:

  1. 次の行をコメントアウトします: f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"

  2. 次の行のコメントを解除します: # f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"

データポリシーが適用された外部クエリエンジンを接続する

ステップ7:Icebergテーブルのクエリ

このステップでは、Apache Spark™を使用してIcebergテーブルをクエリするための次のコード例を示します。

  • 名前空間を表示する

  • 名前空間を使用する

  • Show tables

  • テーブルをクエリする

名前空間を表示する

spark.sql("show namespaces").show()
Copy

Use namespace

spark.sql("use namespace <your_schema_name_in_snowflake>")
Copy

Show tables

spark.sql("show tables").show()
Copy

テーブルをクエリする

spark.sql("use namespace spark_demo")
spark.sql("select * from <your_table_name_in_snowflake>").show()
Copy

外部クエリエンジンを使用してIcebergテーブルをクエリする際の考慮事項

外部クエリエンジンでIcebergテーブルをクエリする場合は、以下の項目を考慮してください:

  • Iceberg

    • Snowflakeのテーブルの場合:

      • Snowflake管理Icebergテーブルのみがサポートされています。

      • 以下のテーブルのクエリはサポートされていません。

        • リモートテーブル

        • Snowflakeネイティブテーブル

        • DeltaベースのIcebergテーブルや、Iceberg互換のParquetデータファイルから COPY INTO テーブルコマンドを使用してデータをロードしたSnowflake管理のIcebergテーブルを含む、外部管理Icebergテーブル。

    • クエリはできますが、Icebergテーブルへの書き込みはできません。

    • 外部読み取りはIcebergのバージョン2以前でのみサポートされています。

  • アクセス制御:

  • ネットワークおよびプライベート接続:

    • ユーザーレベルで設定されたネットワークポリシーの使用は、この機能ではサポートされていません。

    • Snowflakeが管理するネットワークルール の場合、静的であるエグレス IP アドレスはサポートされていません。

    • Horizonカタログエンドポイントのアクセス権をご利用のストレージアカウントに明示的に付与することは、サポートされていません。外部エンジンからHorizonカタログへ、およびHorizonカタログからストレージアカウントへの安全な接続のために、プライベート接続を使用することをお勧めします。

  • リスト:

  • クラウド:

    • この機能は、すべての商用クラウドリージョンで、Amazon S3、Google Cloud、またはMicrosoft Azureに保存されているSnowflake管理のIcebergテーブルでのみサポートされています。S3互換の非 AWS ストレージはまだサポートされていません。

    • Amazon S3に保存されているIcebergテーブルの場合:

      • SSE-KMS 暗号化を使用する場合は、アクセスを有効にする際のサポートについて、カスタマーサポートまたはアカウントチームにお問い合わせください。

    • Azureに保存されているIcebergテーブルの場合:

      • Azure仮想ネットワーク( VNet )はサポートされていません。

  • 認証:

    • キーペア認証について、キーペアのローテーションはサポートされていません。

    • ワークロードIDフェデレーションは、この機能ではサポートされていません。