Tutorial: noções básicas de JSON para o Snowflake

Introdução

Neste tutorial você aprenderá o básico sobre como usar JSON com o Snowflake.

O que você aprenderá

Neste tutorial, você aprenderá a fazer o seguinte:

  • Carregar amostra de dados JSON de um bucket S3 público em uma coluna do tipo variant em uma tabela Snowflake.

  • Testar consultas simples para dados JSON na tabela.

  • Explorar a função FLATTEN para nivelar os dados JSON em uma representação relacional e salvá-los em outra tabela.

  • Explorar maneiras de garantir a singularidade ao inserir linhas na versão nivelada dos dados.

Pré-requisitos

O tutorial considera o seguinte:

  • Você tem uma conta Snowflake configurada para usar Amazon AWS e um usuário com uma função que concede os privilégios necessários para criar um banco de dados, tabelas e objetos de warehouse virtual.

  • Você tem o SnowSQL (cliente CLI) instalado.

O tutorial Snowflake em 20 minutos fornece as instruções passo a passo relacionadas para atender a estes requisitos.

O Snowflake fornece amostras de arquivos de dados em um bucket S3 público para uso neste tutorial. Mas antes de começar, você precisa criar um banco de dados, tabelas, um warehouse virtual e um estágio externo para este tutorial. Estes são os objetos básicos do Snowflake necessários para a maioria das atividades do Snowflake.

Sobre o arquivo de dados de amostra

Para este tutorial, você utiliza os seguintes dados JSON de eventos do aplicativo de amostra fornecidos em um bucket S3 público.

{
"device_type": "server",
"events": [
  {
    "f": 83,
    "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19",
    "t": 1437560931139,
    "v": {
      "ACHZ": 42869,
      "ACV": 709489,
      "DCA": 232,
      "DCV": 62287,
      "ENJR": 2599,
      "ERRS": 205,
      "MXEC": 487,
      "TMPI": 9
    },
    "vd": 54,
    "z": 1437644222811
  },
  {
    "f": 1000083,
    "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22",
    "t": 1437036965027,
    "v": {
      "ACHZ": 6953,
      "ACV": 346795,
      "DCA": 250,
      "DCV": 46066,
      "ENJR": 9033,
      "ERRS": 615,
      "MXEC": 0,
      "TMPI": 112
    },
    "vd": 626,
    "z": 1437660796958
  }
],
"version": 2.6
}
Copy

Os dados representam exemplos de eventos que os aplicativos carregam no S3. Uma variedade de dispositivos e aplicativos, tais como servidores, telefones celulares e navegadores publicam eventos. Em um cenário comum de coleta de dados, um ponto de extremidade escalável da Web coleta dados POSTed de diferentes fontes e os grava em um sistema de enfileiramento. Em seguida, um serviço/utilitário de ingestão grava os dados em um bucket S3, a partir do qual você pode carregar os dados no Snowflake.

Os dados da amostra ilustram os seguintes conceitos:

  • Os aplicativos podem optar por agrupar os eventos em lotes. Um lote é um recipiente que contém informações de cabeçalho comuns a todos os eventos do lote. Por exemplo, o JSON anterior é um lote de dois eventos com informações de cabeçalho comuns: device_type e version que geraram esses eventos.

  • Amazon S3 oferece suporte ao uso do conceito de pastas para organizar um bucket. Os aplicativos podem aproveitar este recurso para dividir os dados de eventos. Os esquemas de particionamento normalmente identificam detalhes, tais como aplicativo ou local que gerou o evento, juntamente com uma data do evento quando foi escrito para S3. Tal esquema de particionamento permite copiar qualquer fração dos dados particionados para o Snowflake com um único comando COPY. Por exemplo, você pode copiar dados de eventos por hora, dados, mês ou ano quando você preencher inicialmente as tabelas.

    Por exemplo:

    s3://bucket_name/application_a/2016/07/01/11/

    s3://bucket_name/application_b/location_c/2016/07/01/14/

    Observe que application_a, application_b, location_c etc. identificam detalhes para a fonte de todos os dados no caminho. Os dados podem ser organizados pela data em que foram gravados. Um diretório opcional de 24 horas reduz a quantidade de dados em cada diretório.

    Nota

    O S3 transmite uma lista de diretórios com cada instrução COPY utilizada pelo Snowflake, por isso reduzir o número de arquivos em cada diretório melhora o desempenho de suas instruções COPY. Você pode até considerar a criação de pastas de incrementos de 10-15 minutos em cada hora.

    A amostra de dados fornecida no bucket S3 utiliza um esquema de particionamento semelhante. Em um comando COPY, você especificará um caminho de pasta específico para copiar os dados de eventos.

Criação de banco de dados, tabela, warehouse e estágio externo

Execute as seguintes instruções para criar um banco de dados, uma tabela, um warehouse virtual e um estágio externo necessário para este tutorial. Depois de concluir o tutorial, você poderá descartar estes objetos.

CREATE OR REPLACE DATABASE mydatabase;

USE SCHEMA mydatabase.public;

CREATE OR REPLACE TABLE raw_source (
  SRC VARIANT);

CREATE OR REPLACE WAREHOUSE mywarehouse WITH
  WAREHOUSE_SIZE='X-SMALL'
  AUTO_SUSPEND = 120
  AUTO_RESUME = TRUE
  INITIALLY_SUSPENDED=TRUE;

USE WAREHOUSE mywarehouse;

CREATE OR REPLACE STAGE my_stage
  URL = 's3://snowflake-docs/tutorials/json';
Copy

Observe o seguinte:

  • A instrução CREATE DATABASE cria um banco de dados. O banco de dados inclui automaticamente um esquema chamado “public”.

  • A instrução USE SCHEMA especifica um banco de dados e um esquema ativo para a sessão atual do usuário. Especificar um banco de dados agora permite que você realize seu trabalho neste banco de dados sem ter que fornecer o nome cada vez que for solicitado.

  • A instrução CREATE TABLE cria uma tabela de destino para os dados JSON.

  • A instrução CREATE WAREHOUSE cria um warehouse inicialmente suspenso. A instrução também define AUTO_RESUME = true, que inicia automaticamente o warehouse quando você executa instruções SQL que exigem recursos computacionais. A instrução USE WAREHOUSE especifica o warehouse que você criou como o warehouse ativo para a sessão atual do usuário.

  • A instrução CREATE STAGE cria um estágio externo que aponta para o bucket S3 contendo o arquivo de amostra para este tutorial.

Copiar dados para a tabela de destino

Execute COPY INTO <tabela> para carregar os dados preparados na tabela RAW_SOURCE de destino.

COPY INTO raw_source
  FROM @my_stage/server/2.6/2016/07/15/15
  FILE_FORMAT = (TYPE = JSON);
Copy

O comando copia todos os novos dados do caminho especificado no estágio externo para a tabela RAW_SOURCE de destino. Neste exemplo, o caminho especificado tem como alvo os dados gravados na 15ª hora (3 PM) de 15 de julho de 2016. Observe que o Snowflake verifica o valor S3 ETag de cada arquivo para garantir que ele seja copiado apenas uma vez.

Execute uma consulta SELECT para verificar se os dados foram copiados com sucesso.

SELECT * FROM raw_source;
Copy

A consulta retorna o seguinte resultado:

+-----------------------------------------------------------------------------------+
| SRC                                                                               |
|-----------------------------------------------------------------------------------|
| {                                                                                 |
|   "device_type": "server",                                                        |
|   "events": [                                                                     |
|     {                                                                             |
|       "f": 83,                                                                    |
|       "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19",   |
|       "t": 1437560931139,                                                         |
|       "v": {                                                                      |
|         "ACHZ": 42869,                                                            |
|         "ACV": 709489,                                                            |
|         "DCA": 232,                                                               |
|         "DCV": 62287,                                                             |
|         "ENJR": 2599,                                                             |
|         "ERRS": 205,                                                              |
|         "MXEC": 487,                                                              |
|         "TMPI": 9                                                                 |
|       },                                                                          |
|       "vd": 54,                                                                   |
|       "z": 1437644222811                                                          |
|     },                                                                            |
|     {                                                                             |
|       "f": 1000083,                                                               |
|       "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22", |
|       "t": 1437036965027,                                                         |
|       "v": {                                                                      |
|         "ACHZ": 6953,                                                             |
|         "ACV": 346795,                                                            |
|         "DCA": 250,                                                               |
|         "DCV": 46066,                                                             |
|         "ENJR": 9033,                                                             |
|         "ERRS": 615,                                                              |
|         "MXEC": 0,                                                                |
|         "TMPI": 112                                                               |
|       },                                                                          |
|       "vd": 626,                                                                  |
|       "z": 1437660796958                                                          |
|     }                                                                             |
|   ],                                                                              |
|   "version": 2.6                                                                  |
| }                                                                                 |
+-----------------------------------------------------------------------------------+
Copy

Nesta amostra de dados JSON, há dois eventos. Os valores de chave device_type e version identificam uma fonte de dados e uma versão para eventos de um dispositivo específico.

Consultar dados

Nesta seção, você explorará as instruções SELECT para consultar os dados JSON.

  1. Recupere device_type.

    SELECT src:device_type
      FROM raw_source;
    
    Copy

    A consulta retorna o seguinte resultado:

    +-----------------+
    | SRC:DEVICE_TYPE |
    |-----------------|
    | "server"        |
    +-----------------+
    
    Copy

    A consulta usa a notação src:device_type para especificar o nome da coluna e o nome do elemento JSON a ser recuperado. Esta notação é semelhante à conhecida notação SQL table.column. Snowflake permite especificar uma subcoluna dentro de uma coluna principal, que o Snowflake deriva dinamicamente da definição do esquema integrado nos dados JSON. Para obter mais informações, consulte Consulta de dados semiestruturados.

    Nota

    O nome da coluna não diferencia maiúsculas de minúsculas, porém os nomes do elemento JSON diferenciam maiúsculas e minúsculas.

  2. Recupere o valor device_type sem as aspas.

    A consulta anterior retorna o valor dos dados JSON entre aspas. Você pode remover as aspas convertendo os dados em um tipo de dados específico, neste exemplo uma cadeia de caracteres.

    Esta consulta também atribui opcionalmente um nome à coluna usando um alias.

    SELECT src:device_type::string AS device_type
      FROM raw_source;
    
    Copy

    A consulta retorna o seguinte resultado:

    +-------------+
    | DEVICE_TYPE |
    |-------------|
    | server      |
    +-------------+
    
    Copy
  3. Recupere as chaves repetidas f aninhadas dentro dos objetos de eventos da matriz.

    Os dados da amostra JSON incluem a matriz events. Cada objeto de evento na matriz tem o campo f como mostrado.

    {
    "device_type": "server",
    "events": [
      {
        "f": 83,
        ..
      }
      {
        "f": 1000083,
        ..
      }
    ]}
    
    Copy

    Para recuperar estas chaves aninhadas, você pode usar a função FLATTEN. A função nivela os eventos em linhas separadas.

    SELECT
      value:f::number
      FROM
        raw_source
      , LATERAL FLATTEN( INPUT => SRC:events );
    
    Copy

    A consulta retorna o seguinte resultado:

    +-----------------+
    | VALUE:F::NUMBER |
    |-----------------|
    |              83 |
    |         1000083 |
    +-----------------+
    
    Copy

    Observe que value é uma das colunas que a função FLATTEN retorna. O próximo passo fornece mais detalhes sobre o uso da função FLATTEN.

Nivelar dados

FLATTEN é uma função de tabela que produz uma exibição lateral de uma coluna VARIANT, OBJECT ou ARRAY. Nesta etapa, você usa esta função para explorar diferentes níveis de nivelamento.

Nivelamento dos objetos da matriz em uma coluna de variantes

Você pode nivelar os objetos de eventos na matriz events em linhas separadas usando a função FLATTEN. A saída da função inclui uma coluna VALUE que armazena esses eventos individuais.

Você pode então usar o modificador LATERAL para unir a saída da função FLATTEN com qualquer informação fora do objeto - neste exemplo, device_type e version.

  1. Consulte os dados para cada evento:

    SELECT src:device_type::string,
        src:version::String,
        VALUE
    FROM
        raw_source,
        LATERAL FLATTEN( INPUT => SRC:events );
    
    Copy

    A consulta retorna o seguinte resultado:

    +-------------------------+---------------------+-------------------------------------------------------------------------------+
    | SRC:DEVICE_TYPE::STRING | SRC:VERSION::STRING | VALUE                                                                         |
    |-------------------------+---------------------+-------------------------------------------------------------------------------|
    | server                  | 2.6                 | {                                                                             |
    |                         |                     |   "f": 83,                                                                    |
    |                         |                     |   "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19",   |
    |                         |                     |   "t": 1437560931139,                                                         |
    |                         |                     |   "v": {                                                                      |
    |                         |                     |     "ACHZ": 42869,                                                            |
    |                         |                     |     "ACV": 709489,                                                            |
    |                         |                     |     "DCA": 232,                                                               |
    |                         |                     |     "DCV": 62287,                                                             |
    |                         |                     |     "ENJR": 2599,                                                             |
    |                         |                     |     "ERRS": 205,                                                              |
    |                         |                     |     "MXEC": 487,                                                              |
    |                         |                     |     "TMPI": 9                                                                 |
    |                         |                     |   },                                                                          |
    |                         |                     |   "vd": 54,                                                                   |
    |                         |                     |   "z": 1437644222811                                                          |
    |                         |                     | }                                                                             |
    | server                  | 2.6                 | {                                                                             |
    |                         |                     |   "f": 1000083,                                                               |
    |                         |                     |   "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22", |
    |                         |                     |   "t": 1437036965027,                                                         |
    |                         |                     |   "v": {                                                                      |
    |                         |                     |     "ACHZ": 6953,                                                             |
    |                         |                     |     "ACV": 346795,                                                            |
    |                         |                     |     "DCA": 250,                                                               |
    |                         |                     |     "DCV": 46066,                                                             |
    |                         |                     |     "ENJR": 9033,                                                             |
    |                         |                     |     "ERRS": 615,                                                              |
    |                         |                     |     "MXEC": 0,                                                                |
    |                         |                     |     "TMPI": 112                                                               |
    |                         |                     |   },                                                                          |
    |                         |                     |   "vd": 626,                                                                  |
    |                         |                     |   "z": 1437660796958                                                          |
    |                         |                     | }                                                                             |
    +-------------------------+---------------------+-------------------------------------------------------------------------------+
    
  2. Use uma instrução CREATE TABLE AS SELECT para armazenar o resultado da consulta anterior em uma tabela:

    CREATE OR REPLACE TABLE flattened_source AS
      SELECT
        src:device_type::string AS device_type,
        src:version::string     AS version,
        VALUE                   AS src
      FROM
        raw_source,
        LATERAL FLATTEN( INPUT => SRC:events );
    
    Copy

    Consulte a tabela resultante.

    SELECT * FROM flattened_source;
    
    Copy

    A consulta retorna o seguinte resultado:

    +-------------+---------+-------------------------------------------------------------------------------+
    | DEVICE_TYPE | VERSION | SRC                                                                           |
    |-------------+---------+-------------------------------------------------------------------------------|
    | server      | 2.6     | {                                                                             |
    |             |         |   "f": 83,                                                                    |
    |             |         |   "rv": "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19",   |
    |             |         |   "t": 1437560931139,                                                         |
    |             |         |   "v": {                                                                      |
    |             |         |     "ACHZ": 42869,                                                            |
    |             |         |     "ACV": 709489,                                                            |
    |             |         |     "DCA": 232,                                                               |
    |             |         |     "DCV": 62287,                                                             |
    |             |         |     "ENJR": 2599,                                                             |
    |             |         |     "ERRS": 205,                                                              |
    |             |         |     "MXEC": 487,                                                              |
    |             |         |     "TMPI": 9                                                                 |
    |             |         |   },                                                                          |
    |             |         |   "vd": 54,                                                                   |
    |             |         |   "z": 1437644222811                                                          |
    |             |         | }                                                                             |
    | server      | 2.6     | {                                                                             |
    |             |         |   "f": 1000083,                                                               |
    |             |         |   "rv": "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22", |
    |             |         |   "t": 1437036965027,                                                         |
    |             |         |   "v": {                                                                      |
    |             |         |     "ACHZ": 6953,                                                             |
    |             |         |     "ACV": 346795,                                                            |
    |             |         |     "DCA": 250,                                                               |
    |             |         |     "DCV": 46066,                                                             |
    |             |         |     "ENJR": 9033,                                                             |
    |             |         |     "ERRS": 615,                                                              |
    |             |         |     "MXEC": 0,                                                                |
    |             |         |     "TMPI": 112                                                               |
    |             |         |   },                                                                          |
    |             |         |   "vd": 626,                                                                  |
    |             |         |   "z": 1437660796958                                                          |
    |             |         | }                                                                             |
    +-------------+---------+-------------------------------------------------------------------------------+
    

Nivelamento de chaves de objeto em colunas separadas

No exemplo anterior, você nivelou os objetos do evento na matriz events em linhas separadas. A tabela flattened_source resultante manteve a estrutura do evento na coluna src do tipo VARIANT.

Um benefício de manter os objetos do evento na coluna src do tipo VARIANT é que quando o formato do evento muda, você não precisará recriar e preencher novamente tais tabelas. Mas você também tem a opção de copiar chaves individuais no objeto de evento em colunas digitadas separadamente, como mostrado na consulta a seguir.

A seguinte instrução CREATE TABLE AS SELECT cria uma nova tabela chamada events, com as chaves de objeto de evento armazenadas em colunas separadas. Cada valor é convertido em um tipo de dados apropriado para o valor, usando dois pontos duplos (::), seguido do tipo. Se você omitir a conversão, a coluna assume o tipo de dados VARIANT, que pode conter qualquer valor:

create or replace table events as
  select
    src:device_type::string                             as device_type
  , src:version::string                                 as version
  , value:f::number                                     as f
  , value:rv::variant                                   as rv
  , value:t::number                                     as t
  , value:v.ACHZ::number                                as achz
  , value:v.ACV::number                                 as acv
  , value:v.DCA::number                                 as dca
  , value:v.DCV::number                                 as dcv
  , value:v.ENJR::number                                as enjr
  , value:v.ERRS::number                                as errs
  , value:v.MXEC::number                                as mxec
  , value:v.TMPI::number                                as tmpi
  , value:vd::number                                    as vd
  , value:z::number                                     as z
  from
    raw_source
  , lateral flatten ( input => SRC:events );
Copy

A instrução nivela os dados aninhados na chave EVENTS.SRC:V, adicionando uma coluna separada para cada valor. A instrução produz uma linha para cada par chave/valor. A saída seguinte mostra os dois primeiros registros na nova tabela events:

SELECT * FROM events;

+-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
| DEVICE_TYPE | VERSION |       F | RV                                                                   |             T |  ACHZ |    ACV | DCA |   DCV | ENJR | ERRS | MXEC | TMPI |  VD |             Z |
|-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------|
| server      | 2.6     |      83 | "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19"   | 1437560931139 | 42869 | 709489 | 232 | 62287 | 2599 |  205 |  487 |    9 |  54 | 1437644222811 |
| server      | 2.6     | 1000083 | "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22" | 1437036965027 |  6953 | 346795 | 250 | 46066 | 9033 |  615 |    0 |  112 | 626 | 1437660796958 |
+-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
Copy

Atualizar dados

Até agora, neste tutorial, você fez o seguinte:

  • Copiou dados de evento JSON de amostra de um bucket S3 para a tabela RAW_SOURCE e explorou consultas simples.

  • Você também explorou a função FLATTEN para nivelar os dados JSON e obter uma representação relacional dos dados. Por exemplo, você extraiu as chaves de eventos e armazenou as chaves em colunas separadas em outra tabela EVENTS.

No início, o tutorial explica o cenário de aplicativo onde múltiplas fontes geram eventos e um ponto de extremidade da web o salva em seu bucket S3. Conforme novos eventos são adicionados ao bucket S3, você pode usar um script para copiar continuamente novos dados na tabela RAW_SOURCE. Mas como inserir somente novos dados de eventos na tabela EVENTS ?

Há inúmeras maneiras de manter a consistência dos dados. Esta seção explica duas opções.

Uso de colunas de chave primária para comparação

Nesta seção você adiciona uma chave primária à tabela EVENTS. A chave primária garante a exclusividade.

  1. Examine seus dados JSON em busca de quaisquer valores que sejam naturalmente únicos e que seriam bons candidatos a uma chave primária. Por exemplo, suponha que a combinação de src:device_type e value:rv pode ser uma chave primária. Estas duas chaves JSON correspondem às colunas DEVICE_TYPE e RV da tabela EVENTS.

    Nota

    O Snowflake não impõe a restrição de chave primária. Em vez disso, a restrição serve como metadado que identifica a chave natural no Information Schema.

  2. Adicione a restrição de chave primária à tabela EVENTS:

    ALTER TABLE events ADD CONSTRAINT pk_DeviceType PRIMARY KEY (device_type, rv);
    
    Copy
  3. Insira um novo registro de evento JSON na tabela RAW_SOURCE:

    insert into raw_source
      select
      PARSE_JSON ('{
        "device_type": "cell_phone",
        "events": [
          {
            "f": 79,
            "rv": "786954.67,492.68,3577.48,40.11,343.00,345.8,0.22,8765.22",
            "t": 5769784730576,
            "v": {
              "ACHZ": 75846,
              "ACV": 098355,
              "DCA": 789,
              "DCV": 62287,
              "ENJR": 2234,
              "ERRS": 578,
              "MXEC": 999,
              "TMPI": 9
            },
            "vd": 54,
            "z": 1437644222811
          }
        ],
        "version": 3.2
      }');
    
    Copy
  4. Insira o novo registro que você adicionou à tabela RAW_SOURCE na tabela EVENTS com base em uma comparação dos valores de chave primária:

    insert into events
    select
          src:device_type::string
        , src:version::string
        , value:f::number
        , value:rv::variant
        , value:t::number
        , value:v.ACHZ::number
        , value:v.ACV::number
        , value:v.DCA::number
        , value:v.DCV::number
        , value:v.ENJR::number
        , value:v.ERRS::number
        , value:v.MXEC::number
        , value:v.TMPI::number
        , value:vd::number
        , value:z::number
        from
          raw_source
        , lateral flatten( input => src:events )
        where not exists
        (select 'x'
          from events
          where events.device_type = src:device_type
          and events.rv = value:rv);
    
    Copy

    A consulta da tabela EVENTS mostra a linha adicionada:

    select * from EVENTS;
    
    Copy

    A consulta retorna o seguinte resultado:

    +-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
    | DEVICE_TYPE | VERSION |       F | RV                                                                   |             T |  ACHZ |    ACV | DCA |   DCV | ENJR | ERRS | MXEC | TMPI |  VD |             Z |
    |-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------|
    | server      | 2.6     |      83 | "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19"   | 1437560931139 | 42869 | 709489 | 232 | 62287 | 2599 |  205 |  487 |    9 |  54 | 1437644222811 |
    | server      | 2.6     | 1000083 | "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22" | 1437036965027 |  6953 | 346795 | 250 | 46066 | 9033 |  615 |    0 |  112 | 626 | 1437660796958 |
    | cell_phone  | 3.2     |      79 | "786954.67,492.68,3577.48,40.11,343.00,345.8,0.22,8765.22"           | 5769784730576 | 75846 |  98355 | 789 | 62287 | 2234 |  578 |  999 |    9 |  54 | 1437644222811 |
    +-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
    
    Copy

Uso de todas as colunas para comparação

Se os dados JSON não tiverem campos que possam ser candidatos à chave primária, você poderia comparar todas as chaves JSON repetidas na tabela RAW_SOURCE com os valores das colunas correspondentes na tabela EVENTS.

Não são necessárias alterações em sua tabela EVENTS existente.

  1. Insira um novo registro de evento JSON na tabela RAW_SOURCE:

    insert into raw_source
      select
      parse_json ('{
        "device_type": "web_browser",
        "events": [
          {
            "f": 79,
            "rv": "122375.99,744.89,386.99,12.45,78.08,43.7,9.22,8765.43",
            "t": 5769784730576,
            "v": {
              "ACHZ": 768436,
              "ACV": 9475,
              "DCA": 94835,
              "DCV": 88845,
              "ENJR": 8754,
              "ERRS": 567,
              "MXEC": 823,
              "TMPI": 0
            },
            "vd": 55,
            "z": 8745598047355
          }
        ],
        "version": 8.7
      }');
    
    Copy
  2. Insira o novo registro da tabela RAW_SOURCE na tabela EVENTS com base na comparação de todos os valores chave que se repetem:

    insert into events
    select
          src:device_type::string
        , src:version::string
        , value:f::number
        , value:rv::variant
        , value:t::number
        , value:v.ACHZ::number
        , value:v.ACV::number
        , value:v.DCA::number
        , value:v.DCV::number
        , value:v.ENJR::number
        , value:v.ERRS::number
        , value:v.MXEC::number
        , value:v.TMPI::number
        , value:vd::number
        , value:z::number
        from
          raw_source
        , lateral flatten( input => src:events )
        where not exists
        (select 'x'
          from events
          where events.device_type = src:device_type
          and events.version = src:version
          and events.f = value:f
          and events.rv = value:rv
          and events.t = value:t
          and events.achz = value:v.ACHZ
          and events.acv = value:v.ACV
          and events.dca = value:v.DCA
          and events.dcv = value:v.DCV
          and events.enjr = value:v.ENJR
          and events.errs = value:v.ERRS
          and events.mxec = value:v.MXEC
          and events.tmpi = value:v.TMPI
          and events.vd = value:vd
          and events.z = value:z);
    
    Copy

    A consulta da tabela EVENTS mostra a linha adicionada:

    select * from EVENTS;
    
    Copy

    A consulta retorna o seguinte resultado:

    +-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+
    | DEVICE_TYPE | VERSION |       F | RV                                                                   |             T |   ACHZ |    ACV |   DCA |   DCV | ENJR | ERRS | MXEC | TMPI |  VD |             Z |
    |-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------|
    | server      | 2.6     |      83 | "15219.64,783.63,48674.48,84679.52,27499.78,2178.83,0.42,74900.19"   | 1437560931139 |  42869 | 709489 |   232 | 62287 | 2599 |  205 |  487 |    9 |  54 | 1437644222811 |
    | server      | 2.6     | 1000083 | "8070.52,54470.71,85331.27,9.10,70825.85,65191.82,46564.53,29422.22" | 1437036965027 |   6953 | 346795 |   250 | 46066 | 9033 |  615 |    0 |  112 | 626 | 1437660796958 |
    | cell_phone  | 3.2     |      79 | "786954.67,492.68,3577.48,40.11,343.00,345.8,0.22,8765.22"           | 5769784730576 |  75846 |  98355 |   789 | 62287 | 2234 |  578 |  999 |    9 |  54 | 1437644222811 |
    | web_browser | 8.7     |      79 | "122375.99,744.89,386.99,12.45,78.08,43.7,9.22,8765.43"              | 5769784730576 | 768436 |   9475 | 94835 | 88845 | 8754 |  567 |  823 |    0 |  55 | 8745598047355 |
    +-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+
    
    Copy

Parabéns!

Parabéns, você concluiu esse tutorial com sucesso.

Pontos-chave do tutorial

  • A partição dos dados de evento em seu bucket S3 usando caminhos lógicos e granulares permite copiar um subconjunto dos dados particionados para o Snowflake com um único comando.

  • Notação column:key do Snowflake, semelhante à conhecida notação SQL table.column, permite consultar efetivamente uma coluna dentro da coluna (ou seja, uma subcoluna), que é derivada dinamicamente com base na definição do esquema incorporado nos dados JSON.

  • A função FLATTEN permite analisar os dados JSON em colunas separadas.

  • Várias opções estão disponíveis para atualizar os dados da tabela com base em comparações com arquivos de dados preparados.

Tutorial de limpeza (opcional)

Execute os seguintes comandos DROP <objeto> para retornar o sistema ao seu estado antes de iniciar o tutorial:

DROP DATABASE IF EXISTS mydatabase;
DROP WAREHOUSE IF EXISTS mywarehouse;
Copy

Descartar o banco de dados remove automaticamente todos os objetos do banco de dados filho, tais como tabelas.