Snowflake Horizonカタログを介した外部エンジンを使用して Apache Iceberg™ テーブルにクエリする¶
このプレビューでは、Snowflake Horizonカタログを介する外部クエリエンジンを使用して、Snowflakeが管理する Apache Iceberg™ テーブルに対するクエリのサポートが導入されています。外部エンジンとこの相互運用性を確保するために、 Apache Polaris™(インキュベート中) は Horizonカタログに統合されています。さらに、Horizonカタログは Apache Iceberg™ REST APIs を公開しています。それにより、外部クエリエンジンを使用してテーブルを読み取ることができます。
外部クエリエンジンで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 Iceberg REST カタログ API はすべてのSnowflakeエディションで利用可能です。
その API リクエストは100万件のコールごとに0.5クレジットとして請求され、クラウドサービスとして課金されます。
クロスリージョンデータアクセスの場合、 Snowflakeサービス利用表 に記載されている標準のクロスリージョンデータエグレス料金が適用されます。
注釈
この機能が一般に利用可能になるまで、お客様は請求されません。
始める前に¶
クエリするIcebergテーブルを含むSnowflakeアカウントのアカウント識別子を取得します。手順については、 アカウント識別子 をご参照ください。次の場合にこの識別子を指定します。Icebergテーブルに外部クエリエンジンを接続する 。
Tip
SQL を使用してアカウント識別子を取得するには次のコマンドを実行できます。
SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME();
プライベート接続(オプション)¶
安全な接続のために、Horizon カタログエンドポイントにアクセスする際の、Snowflakeアカウント用 :doc:` インバウンド </user-guide/private-connectivity-inbound>` および :doc:` アウトバウンド </user-guide/private-connectivity-outbound>` プライベート接続の構成を検討してください。
注釈
プライベート接続は、Amazon S3またはAzure Storage(ADLS)に保存されているSnowflake管理のIcebergテーブル用としてのみサポートされます。
外部クエリエンジンを使用してIcebergテーブルをクエリするワークフロー¶
外部クエリエンジンを使用してIcebergテーブルをクエリするには、以下のステップを完了します:
Icebergテーブルを作成します。
アクセス制御を構成します。
認証用のアクセストークンを取得します。
Horizonカタログを介して、外部クエリエンジンをIcebergテーブルに接続します。
Icebergテーブルをクエリします。
ステップ1:Icebergテーブルの作成¶
重要
クエリするSnowflake管理のIcebergテーブルがすでにある場合は、このステップをスキップできます。
このステップでは、Snowflakeをカタログとして使用するSnowflake管理のIcebergテーブルを作成し、外部クエリエンジンでクエリを実行できるようにします。手順については、以下のトピックをご参照ください。
チュートリアル: 初めてのApache Iceberg™テーブルを作成する:データベースを作成し、Snowflake管理のIcebergテーブルを作成し、テーブルにデータをロードする方法を示すチュートリアル。
Snowflake管理のIcebergテーブルを作成する:Snowflake管理のIcebergテーブルを作成するコード例。
ステップ2:アクセス制御の構成¶
重要
Horizonカタログエンドポイントを介してIcebergテーブルにアクセスする場合、ロール名にハイフン(-)を含むSnowflakeロールはサポートされません。
クエリするIcebergテーブルへのアクセスで構成されたロールがすでにある場合は、このステップをスキップできます。
このステップでは、外部クエリエンジンでクエリを実行するSnowflake管理のIcebergテーブルのアクセス制御を構成します。たとえば、Snowflakeでは次のロールを設定できます:
DATA_ENGINEER ロール。データベース内のすべてのスキーマとSnowflake管理のすべてのIcebergテーブルにアクセスできます。
DATA_ANALYST ロール。データベース内の1つのスキーマにアクセスし、そのスキーマ内の2つのSnowflake管理のIcebergテーブルにのみアクセスできます。
手順については、 アクセス制御の構成 をご参照ください。Snowflakeでのアクセス制御の詳細については、 アクセス制御の概要 をご参照ください。
ステップ3:認証用アクセストークンの取得¶
このステップでは、SnowflakeアカウントのHorizonカタログエンドポイントを認証するために必要なアクセストークンを取得します。各ユーザー(サービスまたは人間)用のアクセストークンと、Snowflake管理のIcebergテーブルへのアクセスで構成されたロールを取得する必要があります。たとえば、DATA_ENGINEER ロールを持つユーザーと DATA_ANALYST ロールを持つ別のユーザーに対して、1つのアクセストークンを取得する必要があります。
You specify this access token later when you connect an external query engine to Iceberg tables through Horizon Catalog.
次の認証オプションのいずれかを使用して、アクセストークンを取得できます。
外部 OAuth¶
If you're using External OAuth, generate an access token for your identity provider. For instructions, see 外部 OAuth の概要.
注釈
外部 OAuth の場合は、アクセストークンを指定する代わりに、自動トークン更新を使用してエンジンへの接続を構成することもできます。
キーペア認証¶
If you use key-pair authentication, to obtain an access token, you sign a JSON web token (JWT) with your private key.
The following steps cover how to generate an access token for key-pair authentication:
ステップ1:キーペア認証を構成する¶
このステップでは、次のタスクを実行します。
秘密キーを生成する
公開キーを生成する
秘密キーと公開キーを安全に保管する
Snowflakeユーザーに公開キーを割り当てる権限を付与します。
Snowflakeユーザーに公開キーを割り当てる
ユーザーの公開キーのフィンガープリントを検証する
手順については、 キーペア認証の構成 をご参照ください。
ステップ2:ユーザーにロールを付与する¶
GRANT ROLE コマンドを実行して、クエリするテーブルに対する権限を持つSnowflakeロールをキーペア認証ユーザーに付与します。たとえば、 my_service_user ユーザーに ENGINEER ロールを付与するには、次のコマンドを実行します。
GRANT ROLE ENGINEER to user my_service_user;
ステップ3:JSON ウェブトークン( JWT )を生成する¶
このステップでは、 SnowSQL を使用してキーペア認証用の JSON ウェブトークン( JWT )を生成します。
注釈
使用中のマシンに `SnowSQL<https://www.snowflake.com/developers/downloads/snowsql/>`_ がインストールされている必要があります。
あるいは、Python、Snowflake CLI 、Java、またはNode.jsを使用して JWT を生成することもできます。例については、次のセクションをご参照ください。
SnowSQL を使用して JWT を生成する:
snowsql --private-key-path "<private_key_file>" \
--generate-jwt \
-h "<account_identifier>.snowflakecomputing.com" \
-a "<account_locator>" \
-u "<user_name>"
条件:
<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>is the account identifier for your Snowflake account, in the format<organization_name>-<account_name>. To find the account identifier, see 始める前に. An example of an account identifier ismyorg-myaccount.<account_locator>は、Snowflakeアカウントのアカウントロケーターです。アカウントロケーターを見つけるには、 SnowsightでSnowflakeアカウント情報を見つける を参照し、 Account Details ダイアログで Account locator を確認します。
<user_name>は、ユーザーに公開キーが割り当てられたSnowflakeユーザーのユーザー名です。
Step 4: Generate an access token¶
重要
アクセストークンを生成するには、まず 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>'
条件:
<account_identifier>is the account identifier for your Snowflake account, in the format<organization_name>-<account_name>. To find the account identifier, see 始める前に. An example of an account identifier ismyorg-myaccount.<role>is the Snowflake role that is granted access to Iceberg tables, such as ENGINEER.<JWT_token>は、前のステップで生成した JWT です。
Programmatic access token (PAT)¶
If you use PATs, generate a PAT for authentication.
First, you generate a PAT, which you use to connect an external query engine to Iceberg tables. Then, you generate an access token, which you only use to verify the permissions for your PAT.
ステップ1:PAT を生成する¶
PAT の構成および生成方法の手順については、 認証のためのプログラム アクセス トークンの使用 をご参照ください。
Step 2: Generate an access token for your 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>'
条件:
<account_identifier>is the account identifier for your Snowflake account, in the format<organization_name>-<account_name>. To find the account identifier, see 始める前に. An example of an account identifier ismyorg-myaccount.<role>is the Snowflake role that is granted to your PAT and has access to the Iceberg tables you want to query, such as ENGINEER.<PAT_token>は、前のステップで生成した PAT トークンの値です。
Step 4: Verify access token permissions¶
このステップでは、前のステップで取得したアクセストークンの権限を確認します。
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"
条件:
<account_identifier>is the account identifier for your Snowflake account, in the format<organization_name>-<account_name>. To find the account identifier, see 始める前に. An example of an account identifier ismyorg-myaccount.<access_token>is your access token that you generated. If you're using a PAT, this value is the access token you generated, not the personal access token (PAT) you generated.<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"
条件:
<account_identifier>is the account identifier for your Snowflake account, in the format<organization_name>-<account_name>. To find the account identifier, see 始める前に. An example of an account identifier ismyorg-myaccount.<database_name>は、取得するメタデータのテーブルのデータベースです。<namespace_name>は、取得するメタデータのテーブルの名前空間です。<table_name>は、取得するメタデータのテーブルです。<access_token>is your access token that you generated. If you're using a PAT, this value is the access token you generated, not the personal access token (PAT) you generated.
重要
オブジェクトが小文字で作成された場合でも、データベース名、名前空間、およびテーブル名を すべて大文字 で指定する必要があります。
Step 5: Connect an external query engine to Iceberg tables through Horizon Catalog¶
このステップでは、Horizonカタログを介して外部クエリエンジンをIcebergテーブルに接続します。この接続により、外部クエリエンジンを使用してテーブルをクエリすることができます。
外部エンジンはSnowflakeによって公開される Apache Iceberg™ REST エンドポイントを使用します。Snowflakeアカウントの場合、このエンドポイントは次の形式をとります。
https://<account_identifier>.snowflakecomputing.com/polaris/api/catalog
このステップのコード例は、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
条件:
<account_identifier>is your Snowflake account identifier for the Snowflake account that contains the Iceberg tables that you want to query. To find this identifier, see 始める前に.<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)に保存されている場合は、次のステップを実行します:
次の行をコメントアウトします:
f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"次の行のコメントを解除します:
# 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
条件:
<account_identifier>is your Snowflake account identifier for the Snowflake account that contains the Iceberg tables that you want to query. To find this identifier, see 始める前に.<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)に保存されている場合は、次のステップを実行します:
次の行をコメントアウトします:
f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"次の行のコメントを解除します:
# f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"
Step 6: Query Iceberg tables¶
このステップでは、Apache Spark™を使用してIcebergテーブルをクエリするための次のコード例を示します。
名前空間を表示する
名前空間を使用する
Show tables
テーブルをクエリする
名前空間を表示する¶
spark.sql("show namespaces").show()
Use namespace¶
spark.sql("use namespace <your_schema_name_in_snowflake>")
Show tables¶
spark.sql("show tables").show()
テーブルをクエリする¶
spark.sql("use namespace spark_demo")
spark.sql("select * from <your_table_name_in_snowflake>").show()
外部クエリエンジンを使用してIcebergテーブルをクエリする際の考慮事項¶
外部クエリエンジンでIcebergテーブルをクエリする場合は、以下の項目を考慮してください:
Snowflakeのテーブルの場合:
Snowflake管理Icebergテーブルのみがサポートされています。
Delta DirectテーブルおよびParquet Directテーブル、Snowflakeネイティブテーブルを含む、リモートまたは外部で管理されているIcebergテーブルのクエリはサポートされません。
クエリはできますが、Icebergテーブルへの書き込みはできません。
外部読み取りはIcebergのバージョン2以前でのみサポートされています。
この機能は、すべてのパブリッククラウドリージョンで、Amazon S3、Google Cloud、またはAzureに保存されているSnowflake管理のIcebergテーブルでのみサポートされています。S3互換の非 AWS ストレージはまだサポートされていません。
Horizon Iceberg REST API を介してIcebergテーブルをクエリすることはできません。次のきめ細かいアクセス制御(FGAC)ポリシーがテーブルで定義されている場合は以下のようになります:
行アクセスポリシー
列レベルのセキュリティ
Horizonカタログエンドポイントを介してIcebergテーブルにアクセスする場合、ロール名にハイフン(-)を含むSnowflakeロールはサポートされません。
Horizonカタログエンドポイントのアクセスをお使いのストレージアカウントに明示的に付与することはサポートされていません。外部エンジンからHorizonカタログへ、またHorizonカタログからストレージアカウントへの安全な接続のために、プライベート接続を使用することをお勧めします。