Tratamento de respostas

Este tópico explica como tratar uma resposta da API de SQL.

Neste tópico:

Explicação do fluxo de execução

Por padrão, o Snowflake executa a instrução de forma síncrona e retorna um dos códigos de resposta mostrados no diagrama de fluxo abaixo:

Fluxograma para envio de uma instrução para execução

Como mostrado no diagrama de fluxo acima:

  • Se você tiver enviado uma única instrução que foi executada com sucesso, o Snowflake retornará o código de resposta HTTP 200 e as linhas dos resultados em um objeto ResultSet.

    Use o objeto ResultSet para obter os resultados.

  • Se você tiver enviado várias instruções em uma única solicitação e a solicitação tiver sido processada com sucesso, o Snowflake retornará o código de resposta HTTP 200 e um objeto ResultSet.

    O objeto ResultSet não contém nenhuma linha dos resultados. Em vez disso, o campo data conterá apenas a mensagem “Multiple statements executed successfully”.

    Para obter os dados, você deve obter os identificadores das instruções individuais na solicitação do campo statementHandles. Para cada instrução, envie uma solicitação para verificar o status da execução da instrução. Consulte Como verificar o status de execução da instrução e obter os dados.

    Para obter mais informações sobre o processo de tratamento de uma resposta para uma solicitação que especifica várias instruções SQL, consulte Como obter os resultados de cada instrução SQL na solicitação.

  • Se a instrução levar mais de 45 segundos para ser executada ou se você tiver especificado que a instrução deve ser executada de forma assíncrona, o Snowflake retornará o código de resposta HTTP 202 com um objeto QueryStatus.

    Você pode enviar uma solicitação para o ponto de extremidade especificado pelo campo statementStatusUrl no objeto QueryStatus para verificar o status da execução da instrução. Consulte Como verificar o status de execução da instrução e obter os dados.

    Se você quiser cancelar a execução da instrução, você pode enviar uma solicitação para o /api/v2/statements/statementHandle/cancel, usando o identificador da instrução do campo statementHandle no objeto QueryStatus. Consulte Como cancelar a execução de uma instrução SQL.

Como verificar o status de execução da instrução e obter os dados

Em alguns casos, você precisa enviar uma solicitação para verificar o status de execução de uma instrução:

  • Quando você envia uma instrução SQL para execução, o Snowflake retorna um código de resposta 202 se a execução da instrução ainda não estiver sido concluída ou se você tiver enviado uma consulta assíncrona.

    Para verificar se a instrução terminou de ser executada, você deve enviar uma solicitação para verificar o status da instrução.

  • Se você tiver enviado várias instruções SQL em uma única solicitação, você obterá os resultados de cada instrução individual enviando uma solicitação para verificar o status da instrução.

Em ambos os casos, você envia uma solicitação GET ao ponto de extremidade /api/v2/statements/ e anexa o idenficador da instrução ao final do caminho URL como um parâmetro de caminho. Consulte GET /api/v2/statements/{statementHandle} para obter mais detalhes.

GET /api/v2/statements/{statementHandle}
Copy

{statementHandle} é o identificador da instrução que você deseja verificar. Para obter o identificador da instrução:

  • Se você tiver recebido uma resposta com um código de resposta 202, o corpo da resposta incluirá um objeto QueryStatus. Você pode obter o identificador da instrução no campo statementHandle deste objeto.

    Observe que você também pode obter a URL completa para a solicitação no campo statementStatusUrl deste objeto.

    {
      "code": "090001",
      "sqlState": "00000",
      "message": "successfully executed",
      "statementHandle": "e4ce975e-f7ff-4b5e-b15e-bf25f59371ae",
      "statementStatusUrl": "/api/v2/statements/e4ce975e-f7ff-4b5e-b15e-bf25f59371ae"
    }
    
    Copy
  • Se você tiver enviado uma solicitação contendo várias instruções SQL, o corpo da resposta incluirá um objeto ResultSet contendo um campo statementHandles. Nesse campo, você pode obter os identificadores das instruções individuais.

    {
      ...
      "statementHandles" : [ "019c9fce-0502-f1fc-0000-438300e02412", "019c9fce-0502-f1fc-0000-438300e02416" ],
      ...
    }
    
    Copy

Por exemplo, o seguinte comando curl verifica esse status da instrução com o identificador e4ce975e-f7ff-4b5e-b15e-bf25f59371ae:

curl -i -X GET \
    -H "Authorization: Bearer <jwt>" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "User-Agent: myApplicationName/1.0" \
    -H "X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT" \
    "https://<account_identifier>.snowflakecomputing.com/api/v2/statements/e4ce975e-f7ff-4b5e-b15e-bf25f59371ae"
Copy

onde:

Quando você envia uma solicitação para verificar o status, o Snowflake retorna um dos códigos de resposta mostrados no diagrama de fluxo abaixo:

Fluxograma para verificação do status de uma instrução enviada para execução

Como mostrado no diagrama de fluxo acima:

Como obter os resultados da resposta

Nota

A versão 5.40 do Snowflake introduz mudanças na forma como os dados retornados pela API de SQL do Snowflake são tratados, entre outras mudanças.

Esta seção descreve como obter os resultados de uma resposta utilizando funções mais novas da API de SQL do Snowflake. Para obter mais informações sobre o uso do comportamento mais antigo e preterido, consulte Funcionalidade obsoleta.

Se você enviar uma instrução SQL para execução ou verificar o status de execução da instrução, o Snowflake retornará um objeto ResultSet no corpo da resposta se a instrução tiver sido executada com sucesso.

A API do Snowflake retorna os dados em partições. O Snowflake determina o número de partições e o tamanho de cada partição que é retornada. O tamanho de uma partição é variável e se baseia na quantidade de dados devolvidos pelo Snowflake para uma determinada consulta SQL.

Quando você apresenta uma solicitação, o corpo dessa resposta inclui um campo partitionInfo. Este campo contém uma matriz de objetos e cada uma delas descreve uma partição de dados. Esse primeiro objeto descreve a partição de dados retornados nessa resposta. O resto dos objetos descreve as partições adicionais que você pode obter apresentando solicitações posteriores com partition=partition_number.

Cada objeto da array especifica o número de linhas e o tamanho de uma partição. Seu aplicativo pode usar esses metadados das partições para determinar como lidar com as partições retornadas para solicitações posteriores.

O exemplo a seguir mostra uma parte da resposta:

{
  "code": "090001",
  "statementHandle": "536fad38-b564-4dc5-9892-a4543504df6c",
  "sqlState": "00000",
  "message": "successfully executed",
  "createdOn": 1597090533987,
  "statementStatusUrl": "/api/v2/statements/536fad38-b564-4dc5-9892-a4543504df6c",
  "resultSetMetaData" : {
    "numRows" : 50000,
    "format" : "jsonv2",
    "partitionInfo" : [ {
      "rowCount" : 12288,
      "uncompressedSize" : 124067,
      "compressedSize" : 29591
    }, {
      "rowCount" : 37712,
      "uncompressedSize" : 414841,
      "compressedSize" : 84469
    }],
  },
  "data": [
    ["customer1", "1234 A Avenue", "98765", "2021-01-20
    12:34:56.03459878"],
    ["customer2", "987 B Street", "98765", "2020-05-31
    01:15:43.765432134"],
    ["customer3", "8777 C Blvd", "98765", "2019-07-01
    23:12:55.123467865"],
    ["customer4", "64646 D Circle", "98765", "2021-08-03
    13:43:23.0"]
  ]
}
Copy

Como obter metadados sobre os resultados

No objeto ResultSet retornado na resposta, o campo resultSetMetaData contém um objeto ResultSet_resultSetMetaData que descreve o conjunto de resultados (por exemplo, o formato dos resultados, o número de partições retornadas, etc.).

Como obter metadados sobre as colunas retornadas no objeto ResultSet

O campo resultSetMetaData contém informações sobre as colunas retornadas no objeto ResultSet.

No exemplo abaixo, o campo rowType contém uma array de objetos ResultSet_resultSetMetaData_rowType. Cada objeto descreve uma coluna nos resultados. O campo type especifica o tipo de dados do Snowflake da coluna.

{
 "resultSetMetaData": {
  "numRows": 1300,
  "rowType": [
   {
    "name":"ROWNUM",
    "type":"FIXED",
    "length":0,
    "precision":38,
    "scale":0,
    "nullable":false
   }, {
    "name":"ACCOUNT_NAME",
    "type":"TEXT",
    "length":1024,
    "precision":0,
    "scale":0,
    "nullable":false
   }, {
    "name":"ADDRESS",
    "type":"TEXT",
    "length":16777216,
    "precision":0,
    "scale":0,
    "nullable":true
   }, {
    "name":"ZIP",
    "type":"TEXT",
    "length":100,
    "precision":0,
    "scale":0,
    "nullable":true
   }, {
    "name":"CREATED_ON",
    "type":"TIMESTAMP_NTZ",
    "length":0,
    "precision":0,
    "scale":3,
    "nullable":false
   }],
  "partitionInfo": [{
    ... // Partition metadata
  }]
 }
}
Copy

Como obter metadados sobre as partições retornadas pelo objeto ResultSet

Ao enviar uma solicitação para executar uma consulta, a resposta inclui metadados que descrevem como os dados são particionados entre as respostas, bem como a primeira partição de dados.

O campo resultSetMetaData contém um campo partitionInfo. Esse campo contém um conjunto de objetos, cada um dos quais descreve uma partição de dados. Esse primeiro objeto descreve a partição de dados retornados nessa resposta. O resto dos objetos descreve as partições adicionais que você pode obter apresentando solicitações posteriores com partition=partition_number.

O exemplo a seguir mostra uma parte da resposta:

  {
    "resultSetMetaData": {
    "numRows: 103477,
    "format": "jsonv2"
    "rowType": {
      ... // Column metadata.
    },
    "partitionInfo": [{
        "rowCount": 12344,
        "uncompressedSize": 14384873,
      },{
        "rowCount": 47387,
        "uncompressedSize": 76483423,
        "compressedSize": 4342748
      },{
        "rowCount": 43746,
        "uncompressedSize": 43748274,
        "compressedSize": 746323
    }]
  },
  ...
}
Copy

Neste exemplo, o primeiro objeto no campo partitionInfo descreve a partição de dados no campo de dados dessa resposta.

O segundo objeto descreve a segunda partição de dados, que contém 47.387 linhas e que você pode obter enviando a solicitação

GET /api/v2/statements/handle?partition=1.

O terceiro objeto descreve a terceira partição de dados, que contém 43.746 linhas e que você pode obter enviando a solicitação

GET /api/v2/statements/handle?partition=2.

Como obter os dados a partir dos resultados

No objeto ResultSet na resposta, os resultados estão no campo data. O campo data contém uma array de uma série de cadeias de caracteres em JSON. Por exemplo:

{
  ...
  "data": [
    ["customer1", "1234 A Avenue", "98765", "2021-01-20 12:34:56.03459878"],
    ["customer2", "987 B Street", "98765", "2020-05-31 01:15:43.765432134"],
    ["customer3", "8777 C Blvd", "98765", "2019-07-01 23:12:55.123467865"],
    ["customer4", "64646 D Circle", "98765", "2021-08-03 13:43:23.0"]
  ],
  ...
}
Copy

Cada array dentro da array contém os dados para uma linha. Os elementos em cada matriz representam os dados em uma linha.

Os dados no conjunto de resultados são codificados em JSON expressos como cadeias de caracteres, independentemente do tipo de dados do Snowflake da coluna.

Por exemplo, o valor 1.0 em uma coluna NUMBER é retornado como a cadeia de caracteres "1.0". Como outro exemplo, carimbos de data/hora são retornados como o número de nanossegundos desde a época. Por exemplo, o carimbo de data/hora para quinta-feira, 28 de janeiro de 2021 10:09:37.123456789 PM é retornado como "1611871777123456789".

Você é responsável por converter as cadeias de caracteres para os tipos de dados adequados.

O Snowflake retorna os valores como cadeias de caracteres nos seguintes formatos (se nenhum parâmetro do formato de saída estiver especificado na solicitação de envio da instrução POST), dependendo do tipo de dados do Snowflake:

INT / NUMBER:

Número decimal em uma cadeia de caracteres.

FLOAT:

Integer ou float em uma cadeia de caracteres.

VARCHAR:

Cadeia de caracteres.

BINARY:

Número hexadecimal em uma cadeia de caracteres.

BOOLEAN:

“false” ou “true” em uma cadeia de caracteres.

DATE:

Valor integer (em uma cadeia de caracteres) do número de dias desde a época (por exemplo, 18262).

TIME, TIMESTAMP_LTZ, TIMESTAMP_NTZ:

Valor float (com 9 casas decimais) do número de segundos desde a época (por exemplo, 82919.000000000).

TIMESTAMP_TZ:

Valor float (com 9 casas decimais) do número de segundos desde a época, seguido de um espaço e do deslocamento de fuso horário em minutos (por exemplo, 1616173619000000000 960)

Recuperação de partições adicionais

A API de SQL do Snowflake retorna dados em partições. A primeira partição é retornada no formato JSON e contém metadados sobre todas as partições retornadas para uma consulta específica. Seu aplicativo pode usar esses metadados das partições para determinar como lidar com as partições retornadas para solicitações posteriores.

Após receber a resposta contendo a primeira partição de dados, você pode obter o resto das partições enviando pedidos com partition=partition_number, onde partition_number identifica a partição de dados a retornar. O número da partição 0 identifica a primeira partição de dados, que é retornada na solicitação inicial.

Por exemplo, após receber a primeira partição de dados, você pode obter a segunda partição de dados apresentando uma solicitação com o parâmetro de partição definido como 1:

GET /api/v2/statements/<handle>?partition=1
Copy

Na resposta a uma solicitação GET /api/v2/statements/<handle>?partition=partition_number, o corpo contém dados JSON em formato compactado (usando gzip).

A resposta inclui o cabeçalho HTTP Content-Encoding: gzip, indicando que o corpo da resposta está comprimido.

Essas respostas não contêm nenhum metadado. Os metadados para todas as partições são fornecidos na primeira partição.

Retornando valores NULL de SQL como cadeias de caracteres

Por padrão, valores NULL de SQL são retornados como o valor null:

"data" : [ [ null ], ... ]
Copy

Se, em vez disso, você quiser que esses valores sejam retornados como a cadeia de caracteres "null", defina o parâmetro de consulta nullable como false na solicitação POST para enviar a instrução SQL para execução. Por exemplo:

POST /api/v2/statements?nullable=false
Copy

Isso retorna valores NULL de SQL como "null":

"data" : [ [ "null" ], ... ]
Copy

Nota

Não é possível especificar o parâmetro nullable em solicitações GET para verificar o status da instrução.

Formatação da saída dos resultados da consulta

A API de SQL do Snowflake oferece suporte para parâmetros para formatar a saída (por exemplo, Parâmetros de sessão para datas, horas e carimbos de data/hora).

Por exemplo, por padrão, um valor DATE como 2019-03-27 é retornado como “17982” (2019-03-27 é 17982 dias após a época). Se você especificar que o DATE_OUTPUT_FORMAT deve ser “MM/DD/YY” na solicitação:

{
  "statement": "select date_column from mytable",
  "resultSetMetaData": {
    "format": "jsonv2",
  },
  "parameters": {
    "DATE_OUTPUT_FORMAT": "MM/DD/YYYY"
  }
  ...
}
Copy

O valor DATE é retornado como “03/27/2019”.

No campo parameters no corpo da solicitação, você pode definir os seguintes parâmetros que determinam o formato de saída dos dados:

  • BINARY_OUTPUT_FORMAT

  • DATE_OUTPUT_FORMAT

  • TIME_OUTPUT_FORMAT

  • TIMESTAMP_LTZ_OUTPUT_FORMAT

  • TIMESTAMP_NTZ_OUTPUT_FORMAT

  • TIMESTAMP_TZ_OUTPUT_FORMAT

  • TIMESTAMP_OUTPUT_FORMAT

  • TIMEZONE

Nota

O Snowflake ignora as configurações no nível da conta e de usuário para esses parâmetros. É necessário definir esses parâmetros de saída no corpo da solicitação para alterar o formato dos valores nos resultados da API SQL.

Como incluir números de linha no objeto resultSet

Números de linhas não são retornados no conjunto de resultados. Para incluir números de linha na resposta, chame a função de janela SEQUENCE ou ROW_NUMBER em sua consulta para gerar os números de linha.