Compartilhar via


API de Execução de Instrução: executar o SQL em armazéns

Importante

Para acessar as APIs REST do Databricks, é necessário autenticar-se.

Este tutorial mostra como usar a API de Execução de Instrução SQL no Databricks 2.0 para executar instruções SQL de warehouses do Databricks SQL.

Para exibir a referência da API de Execução da Instrução SQL do Databricks 2.0, confira Execução da Instrução.

Antes de começar

Antes de começar este tutorial, verifique se você possui:

  • A CLI do Databricks versão 0.205 ou superior ou curl, da seguinte maneira:

    • A CLI do Databricks é uma ferramenta de linha de comando para enviar e receber solicitações e respostas da API REST do Databricks. Se você usar a CLI do Databricks versão 0.205 ou superior, ela deverá ser configurada para autenticação com o espaço de trabalho do Azure Databricks. Consulte Instalar ou atualizar a CLI do Databricks e Autenticação para a CLI do Databricks.

      Por exemplo, para se autenticar com a autenticação de token de acesso pessoal do Databricks, crie um token de acesso pessoal da seguinte maneira:

      1. No workspace do Azure Databricks, clique no nome de usuário do Azure Databricks na barra superior e selecione Configurações na lista suspensa.
      2. Clique em Desenvolvedor.
      3. Ao lado de Tokens de acesso, clique em Gerenciar.
      4. Clique em Gerar novo token.
      5. (Opcional) Insira um comentário que ajude você a identificar esse token no futuro e altere o tempo de vida padrão do token de 90 dias. Para criar um token sem tempo de vida (não recomendado), deixe a caixa Tempo de vida (dias) vazia (em branco).
      6. Clique em Gerar.
      7. Copie o token exibido para um local seguro e clique em Concluído.

      Observação

      Lembre-se de salvar o token copiado em um local seguro. Não compartilhe seu token copiado com outras pessoas. Se você perder o token copiado, não poderá regenerar exatamente aquele mesmo token. Em vez disso, será necessário repetir esse procedimento para criar um novo token. Caso você tenha perdido o token copiado ou acredite que ele tenha sido comprometido, o Databricks recomenda que você exclua imediatamente esse token do seu workspace clicando no ícone de lixeira (Revogar) ao lado do token na página de Tokens de acesso.

      Se você não conseguir criar ou usar tokens em seu workspace, isso pode ocorrer porque o administrador do workspace desabilitou tokens ou não deu permissão para criar ou usar tokens. Consulte o administrador do espaço de trabalho ou os seguintes tópicos:

      Em seguida, para usar a CLI do Databricks para criar um perfil de configuração do Azure Databricks para seu token de acesso pessoal, faça o seguinte:

      Observação

      O procedimento a seguir usa a CLI do Databricks para criar um perfil de configuração do Azure Databricks com o nome DEFAULT. Se você já tiver um perfil de configuração DEFAULT, esse procedimento irá substituir seu perfil de configuração DEFAULT existente.

      Para verificar se você já tem um perfil de configuração do DEFAULT e para exibir as configurações desse perfil, se existir, use a CLI do Databricks para executar o comando databricks auth env --profile DEFAULT.

      Para criar um perfil de configuração com um nome diferente de DEFAULT, substitua a parte DEFAULT de --profile DEFAULT no seguinte comando databricks configure por um nome diferente do perfil de configuração.

      1. Use a CLI do Databricks para criar um perfil de configuração do Azure Databricks chamado DEFAULT que esteja usando a autenticação de token de acesso pessoal do Azure Databricks. Para fazer isso, execute o seguinte comando:

        databricks configure --profile DEFAULT
        
      2. Para o prompt de Host do Databricks, insira sua URL de por workspace do Azure Databricks, por exemplo, https://adb-1234567890123456.7.azuredatabricks.net.

      3. No prompt Token de Acesso Pessoal, insira o token de acesso pessoal do Azure Databricks do seu workspace.

      Nos exemplos de CLI do Databricks deste tutorial, observe o seguinte:

      • Este tutorial pressupõe que você tenha uma variável de ambiente DATABRICKS_SQL_WAREHOUSE_ID em seu computador de desenvolvimento local. Essa variável de ambiente representa a ID do seu SQL warehouse do Databricks. Essa ID é a cadeia de caracteres de letras e números que segue /sql/1.0/warehouses/ no campo de caminho HTTP para seu warehouse. Para saber como obter o valor do caminho HTTP do seu warehouse, confiraObter detalhes de conexão para um recurso de computação do Azure Databricks.
      • Se você usar o shell de comando do Windows em vez de um shell de comando para Unix, Linux ou macOS, substitua \ por ^ e substitua ${...}por %...%.
      • Se você usar o shell de comando do Windows em vez de um shell de comando para Unix, Linux ou macOS, em declarações de documento JSON, substitua o ' de abertura e fechamento por " e substitua o " interno por \".
    • O curl é uma ferramenta de linha de comando para enviar e receber solicitações e respostas da API REST. Confira também Instalar curl. Você também pode adaptar os exemplos curl deste tutorial para uso com ferramentas semelhantes, como HTTPie.

      Nos exemplos de curl deste tutorial, observe o seguinte:

      • Em vez de --header "Authorization: Bearer ${DATABRICKS_TOKEN}", você pode usar um arquivo .netrc. Se você usar um arquivo .netrc, substitua --header "Authorization: Bearer ${DATABRICKS_TOKEN}"por --netrc.
      • Se você usar o shell de comando do Windows em vez de um shell de comando para Unix, Linux ou macOS, substitua \ por ^ e substitua ${...}por %...%.
      • Se você usar o shell de comando do Windows em vez de um shell de comando para Unix, Linux ou macOS, em declarações de documento JSON, substitua o ' de abertura e fechamento por " e substitua o " interno por \".

      Além disso, para os exemplos de curl deste tutorial, ele pressupõe que você tenha as seguintes variáveis de ambiente em seu computador de desenvolvimento local:

      • DATABRICKS_HOST, representando o nome da instância do workspace, por exemplo adb-1234567890123456.7.azuredatabricks.net, para seu workspace do Azure Databricks.
      • DATABRICKS_TOKEN, representando um token de acesso pessoal do Azure Databricks para seu usuário do workspace do Azure Databricks.
      • DATABRICKS_SQL_WAREHOUSE_ID, representando a ID do seu SQL warehouse do Databricks. Essa ID é a cadeia de caracteres de letras e números que segue /sql/1.0/warehouses/ no campo de caminho HTTP para seu warehouse. Para saber como obter o valor do caminho HTTP do seu warehouse, confiraObter detalhes de conexão para um recurso de computação do Azure Databricks.

      Observação

      Como melhor prática de segurança, ao autenticar com ferramentas, sistemas, scripts e aplicativos automatizados, o Databricks recomenda que você use tokens de acesso pertencentes às entidades de serviço e não aos usuários do workspace. Para criar tokens para entidades de serviço, consulte Gerenciar tokens para uma entidade de serviço.

      Para criar um token de acesso pessoal do Azure Databricks, faça o seguinte:

      1. No workspace do Azure Databricks, clique no nome de usuário do Azure Databricks na barra superior e selecione Configurações na lista suspensa.
      2. Clique em Desenvolvedor.
      3. Ao lado de Tokens de acesso, clique em Gerenciar.
      4. Clique em Gerar novo token.
      5. (Opcional) Insira um comentário que ajude você a identificar esse token no futuro e altere o tempo de vida padrão do token de 90 dias. Para criar um token sem tempo de vida (não recomendado), deixe a caixa Tempo de vida (dias) vazia (em branco).
      6. Clique em Gerar.
      7. Copie o token exibido para um local seguro e clique em Concluído.

      Observação

      Lembre-se de salvar o token copiado em um local seguro. Não compartilhe seu token copiado com outras pessoas. Se você perder o token copiado, não poderá regenerar exatamente aquele mesmo token. Em vez disso, será necessário repetir esse procedimento para criar um novo token. Caso você tenha perdido o token copiado ou acredite que ele tenha sido comprometido, o Databricks recomenda que você exclua imediatamente esse token do seu workspace clicando no ícone de lixeira (Revogar) ao lado do token na página de Tokens de acesso.

      Se você não conseguir criar ou usar tokens em seu workspace, isso pode ocorrer porque o administrador do workspace desabilitou tokens ou não deu permissão para criar ou usar tokens. Consulte o administrador do espaço de trabalho ou os seguintes tópicos:

      Aviso

      O Databricks desaconselha fortemente o hard-coding de informações em scripts, pois essas informações confidenciais podem ser expostas em texto sem formatação por meio de sistemas de controle de versão. O Databricks recomenda que você use abordagens como variáveis de ambiente definidas em seu computador de desenvolvimento. Remover essas informações embutidas em código de seus scripts também ajuda a tornar esses scripts mais portáteis.

  • Este tutorial pressupõe que você também tenha o jq, um processador de linha de comando para consultar conteúdos de resposta JSON, que a API de execução de instruções SQL da Databricks retorna para você após cada chamada que você faz para a API de execução de instruções SQL do Databricks. Confira Baixar jq.

  • Você deve ter pelo menos uma tabela na qual possa executar instruções SQL. Este tutorial é baseado na tabela lineitem no esquema tpch (também conhecido como banco de dados) dentro do catálogo samples. Se você não tiver acesso a esse catálogo, esquema ou tabela do seu workspace, substitua-os ao longo deste tutorial pelos seus.

Etapa 1: executar uma instrução SQL e salvar o resultado dos dados como JSON

Execute o comando a seguir, que faz o seguinte:

  1. Usa o SQL warehouse especificado, juntamente com o token especificado se você estiver usando curl, para consultar três colunas das duas primeiras linhas da tabela lineitem no esquema tcph dentro do catálogo samples.
  2. Salva o conteúdo da resposta no formato JSON em um arquivo chamado sql-execution-response.json no diretório de trabalho atual.
  3. Imprime o conteúdo do arquivo sql-execution-response.json.
  4. Define uma variável de ambiente local chamada SQL_STATEMENT_ID. Essa variável contém a ID da instrução SQL correspondente. Você pode usar essa ID de instrução SQL para obter informações sobre essa instrução posteriormente, conforme necessário, o que é demonstrado na Etapa 2. Você também pode exibir essa instrução SQL e obter sua ID de instrução na seção de histórico de consultas do console SQL do Databricks ou chamando a API de Histórico de Consultas.
  5. Define uma variável de ambiente local adicional chamada NEXT_CHUNK_EXTERNAL_LINK que contém um fragmento de URL de API para obter a parte seguinte dos dados JSON. Se os dados de resposta forem muito grandes, a API de Execução de Instrução SQL no Databricks fornecerá a resposta em partes. Você pode usar esse fragmento de URL de API para obter a parte seguinte dos dados, o que é demonstrado na Etapa 2. Se não houver nenhuma parte seguinte, essa variável de ambiente será definida como null.
  6. Imprime os valores das variáveis de ambiente SQL_STATEMENT_ID e NEXT_CHUNK_INTERNAL_LINK.

CLI do Databricks

databricks api post /api/2.0/sql/statements \
--profile <profile-name> \
--json '{
  "warehouse_id": "'"$DATABRICKS_SQL_WAREHOUSE_ID"'",
  "catalog": "samples",
  "schema": "tpch",
  "statement": "SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem WHERE l_extendedprice > :extended_price AND l_shipdate > :ship_date LIMIT :row_limit",
  "parameters": [
    { "name": "extended_price", "value": "60000", "type": "DECIMAL(18,2)" },
    { "name": "ship_date", "value": "1995-01-01", "type": "DATE" },
    { "name": "row_limit", "value": "2", "type": "INT" }
  ]
}' \
> 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export SQL_STATEMENT_ID=$(jq -r .statement_id 'sql-execution-response.json') \
&& export NEXT_CHUNK_INTERNAL_LINK=$(jq -r .result.next_chunk_internal_link 'sql-execution-response.json') \
&& echo SQL_STATEMENT_ID=$SQL_STATEMENT_ID \
&& echo NEXT_CHUNK_INTERNAL_LINK=$NEXT_CHUNK_INTERNAL_LINK

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request POST \
https://${DATABRICKS_HOST}/api/2.0/sql/statements/ \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}" \
--header "Content-Type: application/json" \
--data '{
  "warehouse_id": "'"$DATABRICKS_SQL_WAREHOUSE_ID"'",
  "catalog": "samples",
  "schema": "tpch",
  "statement": "SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem WHERE l_extendedprice > :extended_price AND l_shipdate > :ship_date LIMIT :row_limit",
  "parameters": [
    { "name": "extended_price", "value": "60000", "type": "DECIMAL(18,2)" },
    { "name": "ship_date", "value": "1995-01-01", "type": "DATE" },
    { "name": "row_limit", "value": "2", "type": "INT" }
  ]
}' \
--output 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export SQL_STATEMENT_ID=$(jq -r .statement_id 'sql-execution-response.json') \
&& export NEXT_CHUNK_INTERNAL_LINK=$(jq -r .result.next_chunk_internal_link 'sql-execution-response.json') \
&& echo SQL_STATEMENT_ID=$SQL_STATEMENT_ID \
&& echo NEXT_CHUNK_INTERNAL_LINK=$NEXT_CHUNK_INTERNAL_LINK

Na solicitação anterior:

  • As consultas parametrizadas consistem no nome de cada parâmetro de consulta precedido por dois pontos (por exemplo, :extended_price) com um objeto name e value correspondente na matriz parameters. Um type opcional também pode ser especificado, com o valor padrão de STRING se não for especificado.

    Aviso

    O Databricks recomenda fortemente que você use parâmetros como uma prática recomendada para suas instruções SQL.

    Se você usar a API de Execução de Instrução SQL do Databricks com um aplicativo que gera SQL dinamicamente, isso poderá resultar em ataques de injeção de SQL. Por exemplo, se você gerar código SQL com base nas seleções de um usuário em uma interface do usuário e não tomar as medidas apropriadas, um invasor poderá injetar código SQL mal-intencionado para alterar a lógica da consulta inicial, lendo, alterando ou excluindo dados confidenciais.

    Consultas parametrizadas ajudam a proteger contra ataques de injeções de SQL manipulando argumentos de entrada separadamente do restante do código SQL e interpretando esses argumentos como valores literais. Os parâmetros também ajudam na reutilização de código.

  • Por padrão, todos os dados retornados estão no formato de matriz JSON e o local padrão para qualquer um dos resultados de dados da instrução SQL está dentro do conteúdo da resposta. Para tornar esse comportamento explícito, adicione "format":"JSON_ARRAY","disposition":"INLINE" ao conteúdo da solicitação. Se você tentar retornar resultados de dados maiores que 25 MiB no conteúdo de resposta, um status de falha será retornado e a instrução SQL será cancelada. Para resultados de dados maiores que 25 MiB, você pode usar links externos em vez de tentar devolvê-los no conteúdo de resposta, o que é demonstrado na Etapa 3.

  • O comando armazena o conteúdo do payload de resposta em um arquivo local. O armazenamento de dados local não é compatível diretamente com a API de Execução de Instrução SQL no Databricks.

  • Por padrão, após 10 segundos, se a instrução SQL ainda não tiver sido executada por meio do warehouse, a API de Execução de Instrução SQL no Databricks retornará apenas a ID da instrução SQL e seu status atual em vez de o resultado da instrução. Para alterar esse comportamento, adicione "wait_timeout" à solicitação e defina como "<x>s", onde <x> pode ser entre 5 e 50 segundos; por exemplo "50s". Para retornar a ID da instrução SQL e seu status atual imediatamente, defina wait_timeout como 0s.

  • Por padrão, a instrução SQL continuará sendo executada se o período de tempo limite for atingido. Para cancelar uma instrução SQL se o período de tempo limite for atingido, adicione "on_wait_timeout":"CANCEL" ao conteúdo da solicitação.

  • Para limitar o número de bytes retornados, adicione "byte_limit" à solicitação e defina como o número de bytes, por exemplo 1000.

  • Para limitar o número de linhas retornadas, em vez de adicionar uma cláusula LIMIT a statement, você pode adicionar "row_limit" à solicitação e definr para o número de linhas, por exemplo "statement":"SELECT * FROM lineitem","row_limit":2.

  • Se o resultado for maior do que o byte_limit ou row_limit especificado, o campo truncated será definido como true no conteúdo da resposta.

Se o resultado da instrução estiver disponível antes do término do tempo limite de espera, a resposta será a seguinte:

{
  "manifest": {
    "chunks": [
      {
        "chunk_index": 0,
        "row_count": 2,
        "row_offset": 0
      }
    ],
    "format": "JSON_ARRAY",
    "schema": {
      "column_count": 3,
      "columns": [
        {
          "name": "l_orderkey",
          "position": 0,
          "type_name": "LONG",
          "type_text": "BIGINT"
        },
        {
          "name": "l_extendedprice",
          "position": 1,
          "type_name": "DECIMAL",
          "type_precision": 18,
          "type_scale": 2,
          "type_text": "DECIMAL(18,2)"
        },
        {
          "name": "l_shipdate",
          "position": 2,
          "type_name": "DATE",
          "type_text": "DATE"
        }
      ]
    },
    "total_chunk_count": 1,
    "total_row_count": 2,
    "truncated": false
  },
  "result": {
    "chunk_index": 0,
    "data_array": [
      [
        "2",
        "71433.16",
        "1997-01-28"
      ],
      [
        "7",
        "86152.02",
        "1996-01-15"
      ]
    ],
    "row_count": 2,
    "row_offset": 0
  },
  "statement_id": "00000000-0000-0000-0000-000000000000",
  "status": {
    "state": "SUCCEEDED"
  }
}

Se o tempo limite de espera terminar antes que o resultado da instrução esteja disponível, a resposta terá esta aparência:

{
  "statement_id": "00000000-0000-0000-0000-000000000000",
  "status": {
    "state": "PENDING"
  }
}

Se os dados de resultado da instrução forem muito grandes (por exemplo, nesse caso, executando SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem LIMIT 300000), os dados de resultado serão agrupados e serão semelhantes a este. Observe que "...": "..." indica os resultados omitidos aqui para fins de brevidade:

{
  "manifest": {
    "chunks": [
      {
        "chunk_index": 0,
        "row_count": 188416,
        "row_offset": 0
      },
      {
        "chunk_index": 1,
        "row_count": 111584,
        "row_offset": 188416
      }
    ],
    "format":"JSON_ARRAY",
    "schema": {
      "column_count":3,
      "columns": [
        {
          "...": "..."
        }
      ]
    },
    "total_chunk_count": 2,
    "total_row_count": 300000,
    "truncated": false
  },
  "result": {
    "chunk_index": 0,
    "data_array": [
      [
        "2",
        "71433.16",
        "1997-01-28"
      ],
      [
        "..."
      ]
    ],
    "next_chunk_index": 1,
    "next_chunk_internal_link": "/api/2.0/sql/statements/00000000-0000-0000-0000-000000000000/result/chunks/1?row_offset=188416",
    "row_count": 188416,
    "row_offset": 0
  },
  "statement_id": "00000000-0000-0000-0000-000000000000",
  "status": {
    "state": "SUCCEEDED"
  }
}

Etapa 2: obter o status de execução atual e o resultado dos dados de uma instrução como JSON

Você pode usar a ID de uma instrução SQL para obter o status de execução atual dessa instrução e, se a execução tiver sido bem-sucedida, o resultado dessa instrução. Se você esquecer a ID da instrução, poderá obtê-la na seção de histórico de consultas do console SQL da Databricks ou chamando a API de Histórico de Consultas. Por exemplo, você pode continuar a sondagem desse comando verificando sempre se a execução foi bem-sucedida.

Para obter o status de execução atual de uma instrução SQL e, se a execução for bem-sucedida, o resultado dessa instrução e um fragmento de URL de API para obter qualquer parte seguinte dos dados JSON, execute o comando a seguir. Esse comando pressupõe que você tenha uma variável de ambiente em seu computador de desenvolvimento local chamada SQL_STATEMENT_ID, que é definida como o valor da ID da instrução SQL da etapa anterior. É claro que você pode substituir ${SQL_STATEMENT_ID} no comando a seguir pela ID embutida em código da instrução SQL.

CLI do Databricks

databricks api get /api/2.0/sql/statements/${SQL_STATEMENT_ID} \
--profile <profile-name> \
> 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export NEXT_CHUNK_INTERNAL_LINK=$(jq -r .result.next_chunk_internal_link 'sql-execution-response.json') \
&& echo NEXT_CHUNK_INTERNAL_LINK=$NEXT_CHUNK_INTERNAL_LINK

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request GET \
https://${DATABRICKS_HOST}/api/2.0/sql/statements/${SQL_STATEMENT_ID} \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}" \
--output 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export NEXT_CHUNK_INTERNAL_LINK=$(jq -r .result.next_chunk_internal_link 'sql-execution-response.json') \
&& echo NEXT_CHUNK_INTERNAL_LINK=$NEXT_CHUNK_INTERNAL_LINK

Se o NEXT_CHUNK_INTERNAL_LINK for definido como um valor nãonull, você poderá usá-lo para obter a parte seguinte dos dados e assim por diante, por exemplo, com o seguinte comando:

CLI do Databricks

databricks api get /${NEXT_CHUNK_INTERNAL_LINK} \
--profile <profile-name> \
> 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export NEXT_CHUNK_INTERNAL_LINK=$(jq -r .next_chunk_internal_link 'sql-execution-response.json') \
&& echo NEXT_CHUNK_INTERNAL_LINK=$NEXT_CHUNK_INTERNAL_LINK

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request GET \
https://${DATABRICKS_HOST}${NEXT_CHUNK_INTERNAL_LINK} \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}" \
--output 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export NEXT_CHUNK_INTERNAL_LINK=$(jq -r .next_chunk_internal_link 'sql-execution-response.json') \
&& echo NEXT_CHUNK_INTERNAL_LINK=$NEXT_CHUNK_INTERNAL_LINK

Você pode continuar executando o comando anterior, repetidamente, para obter o próximo bloco, e assim por diante. Observe que assim que a última parte é buscada, a instrução SQL é fechada. Após esse fechamento, você não pode usar a ID dessa instrução para obter seu status atual ou buscar mais partes.

Esta seção demonstra uma configuração opcional que usa a disposição EXTERNAL_LINKS para recuperar grandes conjuntos de dados. O local padrão (disposição) para os dados de resultado da instrução SQL está dentro do conteúdo de resposta, mas esses resultados são limitados a 25 MiB. Ao definir disposition para EXTERNAL_LINKS, a resposta contém URLs que você pode usar para buscar as partes dos dados de resultados com HTTP padrão. As URLs apontam para o DBFS interno do workspace, em que as partes de resultado são armazenadas temporariamente.

Aviso

O Databricks recomenda fortemente que você proteja as URLs e os tokens retornados pela disposição EXTERNAL_LINKS.

Quando você usa a disposição EXTERNAL_LINKS, uma URL de SAS (assinatura de acesso compartilhado) é gerada e ela pode ser usada para baixar os resultados diretamente do armazenamento do Azure. Como um token SAS de curta duração é inserido nessa URL SAS, você deve proteger a URL SAS e o token SAS.

Como as URLs SAS já são geradas com tokens SAS temporários inseridos, você não deve definir um cabeçalho Authorization nas solicitações de download.

A disposição EXTERNAL_LINKS pode ser desabilitada mediante solicitação criando um caso de suporte.

Confira também Melhores práticas de segurança.

Observação

O formato e o comportamento da saída do conteúdo de resposta, depois de definidos para uma ID de instrução SQL específica, não podem ser alterados.

Nesse modo, a API permite que você armazene dados de resultado no formato JSON (JSON), no formato CSV (CSV) ou no formato Apache Arrow (ARROW_STREAM), que devem ser consultados separadamente com HTTP. Além disso, ao usar esse modo, não é possível embutir os dados de resultado dentro do conteúdo de resposta.

O comando a seguir demonstra o uso de EXTERNAL_LINKS e do formato Apache Arrow. Use esse padrão em vez da consulta semelhante demonstrada na Etapa 1:

CLI do Databricks

databricks api post /api/2.0/sql/statements/ \
--profile <profile-name> \
--json '{
  "warehouse_id": "'"$DATABRICKS_SQL_WAREHOUSE_ID"'",
  "catalog": "samples",
  "schema": "tpch",
  "format": "ARROW_STREAM",
  "disposition": "EXTERNAL_LINKS",
  "statement": "SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem WHERE l_extendedprice > :extended_price AND l_shipdate > :ship_date LIMIT :row_limit",
  "parameters": [
    { "name": "extended_price", "value": "60000", "type": "DECIMAL(18,2)" },
    { "name": "ship_date", "value": "1995-01-01", "type": "DATE" },
    { "name": "row_limit", "value": "100000", "type": "INT" }
  ]
}' \
> 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export SQL_STATEMENT_ID=$(jq -r .statement_id 'sql-execution-response.json') \
&& echo SQL_STATEMENT_ID=$SQL_STATEMENT_ID

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request POST \
https://${DATABRICKS_HOST}/api/2.0/sql/statements/ \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}" \
--header "Content-Type: application/json" \
--data '{
  "warehouse_id": "'"$DATABRICKS_SQL_WAREHOUSE_ID"'",
  "catalog": "samples",
  "schema": "tpch",
  "format": "ARROW_STREAM",
  "disposition": "EXTERNAL_LINKS",
  "statement": "SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem WHERE l_extendedprice > :extended_price AND l_shipdate > :ship_date LIMIT :row_limit",
  "parameters": [
    { "name": "extended_price", "value": "60000", "type": "DECIMAL(18,2)" },
    { "name": "ship_date", "value": "1995-01-01", "type": "DATE" },
    { "name": "row_limit", "value": "100000", "type": "INT" }
  ]
}' \
--output 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json' \
&& export SQL_STATEMENT_ID=$(jq -r .statement_id 'sql-execution-response.json') \
&& echo SQL_STATEMENT_ID=$SQL_STATEMENT_ID

A resposta é a seguinte:

{
  "manifest": {
    "chunks": [
      {
        "byte_count": 2843848,
        "chunk_index": 0,
        "row_count": 100000,
        "row_offset": 0
      }
    ],
    "format": "ARROW_STREAM",
    "schema": {
      "column_count": 3,
      "columns": [
        {
          "name": "l_orderkey",
          "position": 0,
          "type_name": "LONG",
          "type_text": "BIGINT"
        },
        {
          "name": "l_extendedprice",
          "position": 1,
          "type_name": "DECIMAL",
          "type_precision": 18,
          "type_scale": 2,
          "type_text": "DECIMAL(18,2)"
        },
        {
          "name": "l_shipdate",
          "position": 2,
          "type_name": "DATE",
          "type_text": "DATE"
        }
      ]
    },
    "total_byte_count": 2843848,
    "total_chunk_count": 1,
    "total_row_count": 100000,
    "truncated": false
  },
  "result": {
    "external_links": [
      {
        "byte_count": 2843848,
        "chunk_index": 0,
        "expiration": "<url-expiration-timestamp>",
        "external_link": "<url-to-data-stored-externally>",
        "row_count": 100000,
        "row_offset": 0
      }
    ]
  },
  "statement_id": "00000000-0000-0000-0000-000000000000",
  "status": {
    "state": "SUCCEEDED"
  }
}

Se a solicitação atingir o tempo limite, a resposta terá esta aparência:

{
  "statement_id": "00000000-0000-0000-0000-000000000000",
  "status": {
    "state": "PENDING"
  }
}

Para obter o status de execução atual dessa instrução e, se a execução tiver sido bem-sucedida, o resultado dessa instrução, execute o seguinte comando:

CLI do Databricks

databricks api get /api/2.0/sql/statements/${SQL_STATEMENT_ID} \
--profile <profile-name> \
> 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json'

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request GET \
https://${DATABRICKS_HOST}/api/2.0/sql/statements/${SQL_STATEMENT_ID} \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}" \
--output 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json'

Se a resposta for grande o suficiente (por exemplo, nesse caso, executando SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem sem limite de linha), a resposta terá várias partes, como no exemplo a seguir abaixo. Observe que "...": "..." indica os resultados omitidos aqui para fins de brevidade:

{
  "manifest": {
    "chunks": [
      {
        "byte_count": 11469280,
        "chunk_index": 0,
        "row_count": 403354,
        "row_offset": 0
      },
      {
        "byte_count": 6282464,
        "chunk_index": 1,
        "row_count": 220939,
        "row_offset": 403354
      },
      {
        "...": "..."
      },
      {
        "byte_count": 6322880,
        "chunk_index": 10,
        "row_count": 222355,
        "row_offset": 3113156
      }
    ],
    "format":"ARROW_STREAM",
    "schema": {
      "column_count": 3,
      "columns": [
        {
          "...": "..."
        }
      ]
    },
    "total_byte_count": 94845304,
    "total_chunk_count": 11,
    "total_row_count": 3335511,
    "truncated": false
  },
  "result": {
    "external_links": [
      {
        "byte_count": 11469280,
        "chunk_index": 0,
        "expiration": "<url-expiration-timestamp>",
        "external_link": "<url-to-data-stored-externally>",
        "next_chunk_index": 1,
        "next_chunk_internal_link": "/api/2.0/sql/statements/00000000-0000-0000-0000-000000000000/result/chunks/1?row_offset=403354",
        "row_count": 403354,
        "row_offset": 0
      }
    ]
  },
  "statement_id": "00000000-0000-0000-0000-000000000000",
  "status": {
    "state": "SUCCEEDED"
  }
}

Para baixar os resultados do conteúdo armazenado, você pode executar o comando curl a seguir usando a URL no objeto external_link e especificando onde deseja baixar o arquivo. Não inclua o token do Azure Databricks neste comando:

curl "<url-to-result-stored-externally>" \
--output "<path/to/download/the/file/locally>"

Para baixar uma parte específica dos resultados de um conteúdo transmitido, você pode usar um dos seguintes:

  • O valor next_chunk_index do conteúdo de resposta para a próxima parte (se houver uma próxima parte).
  • Um dos índices de parte do manifesto do conteúdo de resposta para qualquer parte disponível se houver várias partes.

Por exemplo, para obter a parte com chunk_index ou 10 da resposta anterior, execute o seguinte comando:

CLI do Databricks

databricks api get /api/2.0/sql/statements/${SQL_STATEMENT_ID}/result/chunks/10 \
--profile <profile-name> \
> 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json'

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request GET \
https://${DATABRICKS_HOST}/api/2.0/sql/statements/${SQL_STATEMENT_ID}/result/chunks/10 \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}" \
--output 'sql-execution-response.json' \
&& jq . 'sql-execution-response.json'

Observação

A execução do comando anterior retorna uma nova URL SAS.

Para baixar a parte armazenada, use a URL no objeto external_link.

Para obter mais informações sobre o formato do Apache Arrow, consulte:

Etapa 4: cancelar a execução de uma instrução SQL

Se você precisar cancelar uma instrução SQL que ainda não foi bem-sucedida, execute o seguinte comando:

CLI do Databricks

databricks api post /api/2.0/sql/statements/${SQL_STATEMENT_ID}/cancel \
--profile <profile-name> \
--json '{}'

Substitua <profile-name> pelo nome do seu perfil de configuração do Azure Databricks para autenticação.

curl

curl --request POST \
https://${DATABRICKS_HOST}/api/2.0/sql/statements/${SQL_STATEMENT_ID}/cancel \
--header "Authorization: Bearer ${DATABRICKS_TOKEN}"

Melhores práticas de segurança

A API de Execução de Instrução SQL do Databricks aumenta a segurança das transferências de dados usando criptografia TLS (segurança de camada de transporte) de ponta a ponta e credenciais de curta duração, como tokens SAS.

Há várias camadas nesse modelo de segurança. Na camada de transporte, só é possível chamar a API de Execução da Instrução SQL do Databricks usando o TLS 1.2 ou superior. Além disso, os chamadores da API de Execução de Instrução SQL do Databricks devem ser autenticados com um token de acesso pessoal, token de acesso OAuth ou token do Microsoft Entra ID (antigo Azure Active Directory) válido que é mapeado em um usuário que tem o direito de usar o Databricks SQL. Este usuário deve ter acesso PODE USAR para o armazém SQL específico que está sendo usado, e o acesso pode ser restrito com listas de acesso IP. Isso se aplica a todas as solicitações à API de Execução de Instrução SQL no Databricks. Além disso, para executar instruções, o usuário autenticado deve ter permissão para os objetos de dados (como tabelas, exibições e funções) que são usados em cada instrução. Isso é imposto por mecanismos de controle de acesso existentes no Catálogo do Unity ou usando ACLs de tabela. (Consulte Governança de dados com o Catálogo do Unity para obter mais detalhes.) Isso também significa que somente o usuário que executa uma instrução pode fazer solicitações de busca para os resultados da instrução.

O Databricks recomenda as seguintes práticas recomendadas de segurança sempre que você usar a API de Execução de Instrução SQL no Databricks juntamente com a EXTERNAL_LINKS disposição para recuperar grandes conjuntos de dados:

  • Remover o cabeçalho de autorização do Databricks para solicitações de armazenamento do Azure
  • Proteger URLs SAS e tokens SAS

A disposição EXTERNAL_LINKS pode ser desabilitada mediante solicitação criando um caso de suporte. Entre em contato com a equipe de conta do Azure Databricks para fazer essa solicitação.

Remover o cabeçalho de autorização do Databricks para solicitações de armazenamento do Azure

Todas as chamadas para a API de Execução de Instrução SQL do Databricks que usam curl devem incluir um cabeçalho Authorization que contenha credenciais de acesso do Azure Databricks. Não inclua esse cabeçalho Authorization sempre que você baixar dados do armazenamento do Azure. Esse cabeçalho não é necessário e pode expor involuntariamente suas credenciais de acesso do Azure Databricks.

Proteger URLs SAS e tokens SAS

Sempre que você usa a disposição EXTERNAL_LINKS, uma URL SAS de curta duração é gerada e pode ser usada pelo chamador para baixar os resultados diretamente do armazenamento do Azure usando TLS. Como um token SAS de curta duração é inserido nessa URL SAS, você deve proteger a URL SAS e o token SAS.