Consultar tabelas Apache Iceberg™ com um mecanismo externo por meio do Snowflake Horizon Catalog

Esta versão preliminar introduz suporte para consultar tabelas Apache Iceberg™ gerenciadas pelo Snowflake usando um mecanismo de consulta externo por meio do Snowflake Horizon Catalog. Para garantir essa interoperabilidade com mecanismos externos, o Apache Polaris™ (em incubação) está integrado ao Horizon Catalog. Além disso, o Horizon Catalog expõe REST APIs Apache Iceberg™, que permite ler as tabelas usando mecanismos de consulta externos.

Para consultar tabelas Iceberg gerenciadas pelo Snowflake com um mecanismo de consulta externo, você pode usar este recurso em vez de sincronizar tabelas Iceberg gerenciadas pelo Snowflake com o Snowflake Open Catalog. Para obter mais informações sobre o Open Catalog, consulte Visão geral do Snowflake Open Catalog.

Ao conectar um mecanismo de consulta externo às tabelas Iceberg por meio do Horizon Catalog, você pode executar as seguintes tarefas:

  • Usar qualquer mecanismo de consulta externo compatível com o protocolo aberto do REST Iceberg para consultar essas tabelas, como o Apache Spark™.

  • Consultar quaisquer tabelas Iceberg gerenciadas pelo Snowflake, existentes ou novas, em uma conta Snowflake nova ou existente, usando um único ponto de extremidade do Horizon Catalog.

  • Consultar as tabelas usando seus usuários, funções, políticas e autenticação existentes no Snowflake.

  • Usar credenciais fornecidas.

Para obter mais informações sobre o Snowflake Horizon Catalog, consulte Catálogo Snowflake Horizon.

O diagrama a seguir mostra mecanismos de consulta externos lendo tabelas Iceberg gerenciadas pelo Snowflake por meio do Horizon Catalog e o Snowflake lendo e gravando nessas tabelas:

Diagrama que mostra mecanismos de consulta externos lendo tabelas Iceberg gerenciadas pelo Snowflake por meio do Horizon Catalog e o Snowflake lendo e gravando nessas tabelas.

Faturamento

  • A REST API Iceberg do Catálogo Horizon está disponível em todas as edições do Snowflake.

  • As solicitações de API são faturadas como 0,5 crédito por milhão de chamadas e cobradas como serviços de nuvem.

  • Para acesso a dados entre regiões, aplicam-se as tarifas padrão de saída de dados entre regiões, conforme indicado na Tabela de consumo de serviços do Snowflake.

Nota

Os clientes não serão cobrados até que esse recurso esteja disponível para o público em geral.

Antes de começar

Recupere o identificador da conta Snowflake que contém as tabelas Iceberg que você deseja consultar. Para obter instruções, consulte Identificadores de conta. Você especifica esse identificador ao conectar um mecanismo de consulta externo às suas tabelas Iceberg.

Dica

Para obter o identificador da sua conta usando SQL, você pode executar o seguinte comando:

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

Conectividade privada (opcional)

Para conectividade segura, considere configurar a conectividade privada de Entrada e Saída para sua conta Snowflake ao acessar o ponto de extremidade do Horizon Catalog.

Nota

A conectividade privada é compatível apenas com tabelas Iceberg gerenciadas pelo Snowflake e armazenadas no Amazon S3 ou Armazenamento do Azure (ADLS).

Fluxo de trabalho para consultar tabelas Iceberg usando um mecanismo de consulta externo

Para consultar tabelas Iceberg usando um mecanismo de consulta externo, siga estas etapas:

  1. Criar tabelas Iceberg.

  2. Configurar o controle de acesso.

  3. Obter um token de acesso para autenticação.

  4. Conectar um mecanismo de consulta externo às tabelas Iceberg por meio do Horizon Catalog.

  5. Consultar tabelas Iceberg.

Etapa 1: Criar tabelas Iceberg

Importante

Se você já tem tabelas Iceberg gerenciadas pelo Snowflake que deseja consultar, pode pular esta etapa.

Nesta etapa, você cria tabelas Iceberg gerenciadas pelo Snowflake que usam o Snowflake como catálogo, para que possa consultá-las com um mecanismo de consulta externo. Para obter instruções, consulte os seguintes tópicos:

Etapa 2: Configurar o controle de acesso

Importante

  • Funções do Snowflake que incluem o caractere hífen (-) no nome não são compatíveis durante o acesso a tabelas Iceberg por meio do ponto de extremidade do Horizon Catalog.

  • Se você já tiver funções configuradas com acesso às tabelas Iceberg que deseja consultar, poderá ignorar esta etapa.

Nesta etapa, você configura o controle de acesso para as tabelas Iceberg gerenciadas pelo Snowflake que deseja consultar com um mecanismo de consulta externo. Por exemplo, você pode configurar as seguintes funções no Snowflake:

  • Função DATA_ENGINEER, que tem acesso a todos os esquemas e a todas as tabelas Iceberg gerenciadas pelo Snowflake em um banco de dados.

  • Função DATA_ANALYST, que tem acesso a um esquema no banco de dados e somente a duas tabelas Iceberg gerenciadas pelo Snowflake dentro desse esquema.

Para obter instruções, consulte Configuração do controle de acesso. Para obter mais informações sobre o controle de acesso no Snowflake, consulte Visão geral do controle de acesso.

Etapa 3: Obter um token de acesso para autenticação

Nesta etapa, você obtém um token de acesso, necessário para autenticar-se no ponto de extremidade do Horizon Catalog para sua conta Snowflake. Você precisa obter um token de acesso para cada usuário (seja ele de serviço ou humano) e função configurada com acesso às tabelas Iceberg gerenciadas pelo Snowflake. Por exemplo, você precisa obter um token de acesso para um usuário com a função DATA_ENGINEER e outro usuário com a função DATA_ANALYST.

You specify this access token later when you connect an external query engine to Iceberg tables through Horizon Catalog.

Você pode obter um token de acesso usando uma das seguintes opções de autenticação:

OAuth externo

If you’re using External OAuth, generate an access token for your identity provider. For instructions, see Visão geral de External OAuth.

Nota

Para o OAuth externo, como alternativa, você pode configurar sua conexão com o mecanismo com atualização automática de token em vez de especificar um token de acesso.

Autenticação de pares de chaves

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. Configure key-pair authentication

  2. Grant a role to the user

  3. Generate a JSON Web Token (JWT)

  4. Generate an access token

Etapa 1: Configurar autenticação de par de chaves

Nesta etapa, você executa as seguintes tarefas:

  • Gerar uma chave privada

  • Geração de uma chave pública

  • Armazenamento das chaves públicas e privadas com segurança

  • Conceder o privilégio de atribuição de chave pública a um usuário Snowflake

  • Atribuição da chave pública a um usuário do Snowflake

  • Verificação da impressão digital da chave pública do usuário

Para obter instruções, consulte Configuração da autenticação do par de chaves.

Etapa 2: Conceder uma função ao usuário

Execute o comando GRANT ROLE para conceder a função do Snowflake que tem privilégios nas tabelas que você deseja consultar ao usuário com autenticação de par de chaves. Por exemplo, para conceder a função ENGINEER ao usuário my_service_user, execute o seguinte comando:

GRANT ROLE ENGINEER to user my_service_user;
Copy

Etapa 3: Gerar um JSON Web Token (JWT)

Nesta etapa, você usa o SnowSQL para gerar um JSON Web Token (JWT) para autenticação de par de chaves.

Nota

Use o SnowSQL para gerar um JWT:

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

Onde:

  • <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 Antes de começar. An example of an account identifier is myorg-myaccount.

  • <account_locator> é o localizador da sua conta Snowflake.

    Para encontrar o localizador da conta, consulte Como localizar as informações da sua conta Snowflake no Snowsight e confira o localizador da conta na caixa de diálogo Account Details.

  • <user_name> é o nome de um usuário do Snowflake que recebeu a chave pública.

Step 4: Generate an access token

Importante

Para gerar um token de acesso, você deve primeiro gerar um JWT. Primeiro você deve gerar um JWT porque você usa esse JWT para gerar o token de acesso.

Use um comando curl para gerar um token de acesso:

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

Onde:

  • <account_identifier> is the account identifier for your Snowflake account, in the format <organization_name>-<account_name>. To find the account identifier, see Antes de começar. An example of an account identifier is myorg-myaccount.

  • <role> is the Snowflake role that is granted access to Iceberg tables, such as ENGINEER.

  • <JWT_token> é o JWT que você gerou na etapa anterior.

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.

Etapa 1: Gerar um PAT

Para obter instruções sobre como configurar e gerar um PAT, consulte Uso de tokens de acesso programático para autenticação.

Step 2: Generate an access token for your PAT

Nesta etapa, você gera um token de acesso para seu PAT.

Atenção

Você só especifica o token de acesso gerado nesta etapa para verificar as permissões do seu PAT. Quando você conectar um mecanismo de consulta externo às tabelas Iceberg, deverá especificar o PAT que gerou na etapa anterior, e não o token de acesso que você gera nesta etapa.

Use um comando curl para gerar um token de acesso para seu 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

Onde:

  • <account_identifier> is the account identifier for your Snowflake account, in the format <organization_name>-<account_name>. To find the account identifier, see Antes de começar. An example of an account identifier is myorg-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> é o valor do PAT que você gerou na etapa anterior.

Step 4: Verify access token permissions

Nesta etapa, você verifica as permissões do token de acesso obtido na etapa anterior.

Verificar o acesso ao ponto de extremidade IRC no Horizon

Use um comando curl para verificar se você tem permissão para acessar o ponto de extremidade IRC no Horizon:

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

Onde:

  • <account_identifier> is the account identifier for your Snowflake account, in the format <organization_name>-<account_name>. To find the account identifier, see Antes de começar. An example of an account identifier is myorg-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> é o nome do banco de dados que você deseja consultar.

    Importante

    Você deve especificar o nome do banco de dados com todas as letras maiúsculas, mesmo que ele tenha sido criado com letras minúsculas.

Exemplo de valor de retorno:

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

Recuperar os metadados de uma tabela

Você também pode fazer uma solicitação GET para recuperar os metadados de uma tabela. O Snowflake usa a operação loadTable para carregar metadados da tabela do seu catálogo 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

Onde:

  • <account_identifier> is the account identifier for your Snowflake account, in the format <organization_name>-<account_name>. To find the account identifier, see Antes de começar. An example of an account identifier is myorg-myaccount.

  • <database_name> é o banco de dados da tabela com os metadados que você deseja recuperar.

  • <namespace_name> é o namespace da tabela com os metadados que você deseja recuperar.

  • <table_name> é a tabela com os metadados que você deseja recuperar.

  • <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.

Importante

Você deve especificar o banco de dados, os namespaces e os nomes das tabelas com todas as letras maiúsculas, mesmo que o objeto tenha sido criado com letras minúsculas.

Step 5: Connect an external query engine to Iceberg tables through Horizon Catalog

Nesta etapa, você conecta um mecanismo de consulta externo às tabelas Iceberg por meio do Horizon Catalog. Essa conexão permite consultar as tabelas usando o mecanismo de consulta externo.

Os mecanismos externos usam o ponto de extremidade da REST Apache Iceberg™ exposto pelo Snowflake. Para sua conta Snowflake, esse ponto de extremidade tem o seguinte formato:

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

O código de exemplo nesta etapa mostra como configurar uma conexão no Spark e está em PySpark. Para obter mais informações, consulte os seguintes tópicos:

Conectar-se usando OAuth externo ou autenticação por par de chaves.

Use o seguinte código de exemplo para conectar o mecanismo de consulta externo às tabelas Iceberg usando OAuth externo ou autenticação por par de chaves:

# 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

Onde:

  • <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 Antes de começar.

  • <your_access_token> é o seu token de acesso que você obteve. Para obtê-lo, consulte Etapa 3: Obter um token de acesso para autenticação.

    Nota

    Para o OAuth externo, como alternativa, você pode configurar sua conexão com o mecanismo com atualização automática de token em vez de especificar um token de acesso.

  • <database_name> é o nome do banco de dados em sua conta Snowflake que contém as tabelas Iceberg gerenciadas pelo Snowflake que você deseja consultar.

    Nota

    A propriedade .warehouse no Spark espera o nome do seu banco de dados Snowflake, não o nome do seu warehouse Snowflake.

  • <role> é a função no Snowflake que está configurada com acesso às tabelas Iceberg que você deseja consultar. Por exemplo: DATA_ENGINEER.

Importante

Por padrão, o exemplo de código está configurado para tabelas Apache Iceberg™ armazenadas no Amazon S3. Se suas tabelas Iceberg estiverem armazenadas no Armazenamento do Azure (ADLS), execute as seguintes etapas:

  1. Comente a seguinte linha: f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"

  2. Remova o comentário da seguinte linha: # f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"

Conecte-se usando um token de acesso programático (PAT)

Use o código de exemplo a seguir para conectar o mecanismo de consulta externo às tabelas Iceberg usando um token de acesso programático (PAT):

# 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

Onde:

  • <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 Antes de começar.

  • <your_PAT_token> é o PAT que você obteve. Para obtê-lo, consulte Etapa 3: Obter um token de acesso para autenticação.

  • <role> é a função no Snowflake que está configurada com acesso às tabelas Iceberg que você deseja consultar. Por exemplo: DATA_ENGINEER.

  • <database_name> é o nome do banco de dados em sua conta Snowflake que contém as tabelas Iceberg gerenciadas pelo Snowflake que você deseja consultar.

    Nota

    A propriedade .warehouse no Spark espera o nome do seu banco de dados Snowflake, não o nome do seu warehouse Snowflake.

Importante

Por padrão, o exemplo de código está configurado para tabelas Apache Iceberg™ armazenadas no Amazon S3. Se suas tabelas Iceberg estiverem armazenadas no Armazenamento do Azure (ADLS), execute as seguintes etapas:

  1. Comente a seguinte linha: f"org.apache.iceberg:iceberg-aws-bundle:{ICEBERG_VERSION}"

  2. Remova o comentário da seguinte linha: # f"org.apache.iceberg:iceberg-azure-bundle:{ICEBERG_VERSION}"

Step 6: Query Iceberg tables

Esta etapa fornece os seguintes exemplos de código para usar o Apache Spark™ para consultar tabelas Iceberg:

  • Mostrar namespaces

  • Usar namespaces

  • Exibição de tabelas

  • Consulta a uma tabela

Mostrar namespaces

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

Como usar um namespace

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

Exibição de tabelas

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

Consulta a uma tabela

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

Considerações para consultar tabelas Iceberg com um mecanismo de consulta externo

Considere os seguintes itens ao consultar tabelas Iceberg com um mecanismo de consulta externo:

  • Para tabelas no Snowflake:

    • Somente tabelas Iceberg gerenciadas pelo Snowflake são compatíveis.

    • Não é possível consultar tabelas Iceberg remotas ou gerenciadas externamente, incluindo tabelas Delta Direct e Parquet Direct e tabelas nativas do Snowflake.

  • Você pode consultar, mas não pode gravar em tabelas Iceberg.

  • As leituras externas são compatíveis apenas com a versão 2 ou anterior do Iceberg.

  • Esse recurso é compatível apenas com tabelas Iceberg gerenciadas pelo Snowflake e armazenadas no Amazon S3, Google Cloud ou Azure para todas as regiões de nuvem pública. O armazenamento não AWS compatível com S3 ainda não é aceito.

  • Você não poderá consultar uma tabela Iceberg por meio da REST API do Horizon Iceberg se as seguintes políticas de controle de acesso granular (FGAC) estiverem definidas na tabela:

    • Políticas de acesso a linhas

    • Segurança em nível de coluna

  • Funções do Snowflake que incluem o caractere hífen (-) no nome não são compatíveis durante o acesso a tabelas Iceberg por meio do ponto de extremidade do Horizon Catalog.

  • Não é possível conceder explicitamente acesso do ponto de extremidade do Horizon Catalog às suas contas de armazenamento. Recomendamos que você use conectividade privada para conectividade segura de mecanismos externos ao Horizon Catalog e do Horizon Catalog à conta de armazenamento.