Tutoriel : bases JSON pour Snowflake

Introduction

Dans ce tutoriel, vous apprendrez les bases de l’utilisation de JSON avec Snowflake.

Ce que vous apprendrez

Dans ce tutoriel, vous apprendrez à faire ce qui suit :

  • Charger des données JSON d’exemple à partir d’un compartiment S3 public dans une colonne de type variant dans une table Snowflake.

  • Tester des requêtes simples pour des données JSON de la table.

  • Explorer la fonction FLATTEN pour aplatir des données JSON dans une représentation relationnelle et les enregistrer dans une autre table.

  • Explorer les moyens de garantir l’unicité lorsque vous insérez des lignes dans la version aplatie des données.

Conditions préalables

Le tutoriel suppose les éléments suivants :

  • Vous disposez d’un compte Snowflake configuré pour utiliser Amazon AWS et d’un utilisateur avec un rôle qui accorde les privilèges nécessaires pour créer une base de données, des tables et des objets d’entrepôt virtuel.

  • Vous avez installé SnowSQL (CLI client).

Le tutoriel Snowflake en 20 minutes fournit les instructions étape par étape nécessaires pour répondre à ces exigences.

Snowflake fournit des fichiers de données d’exemple dans un compartiment S3 public à utiliser dans ce tutoriel. Mais avant de commencer, vous devez créer une base de données, des tables, un entrepôt virtuel et une zone de préparation externe pour ce tutoriel. Ce sont les objets Snowflake de base nécessaires pour la plupart des activités Snowflake.

À propos du fichier de données d’exemple

Pour ce tutoriel, vous utilisez les données d’application JSON d’exemple fournies dans un compartiment S3 public.

{
"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

Les données représentent des événements d’exemple que les applications chargent vers S3. Une variété de dispositifs et d’applications, tels que des serveurs, des téléphones portables et des navigateurs, publient des événements. Dans un scénario commun de collecte de données, un point de terminaison Web évolutif collecte des données POSTed de différentes sources, et les écrit dans un système de file d’attente. Un service/utilitaire d’ingestion écrit ensuite les données dans un compartiment S3 à partir duquel vous pouvez charger les données dans Snowflake.

Les données d’exemple illustrent les concepts suivants :

  • Les applications peuvent choisir de grouper les événements par lots. Un lot est un conteneur qui contient des informations d’en-tête communes à tous les événements du lot. Par exemple, le JSON précédent est un lot de deux événements ayant des informations d’en-tête communes : device_type et version qui ont généré ces événements.

  • Amazon S3 prend en charge l’utilisation du concept de dossiers pour organiser un compartiment. Les applications peuvent tirer parti de cette fonctionnalité pour partitionner des données d’événements. Les schémas de partitionnement identifient généralement des détails, tels que l’application ou l’emplacement qui a généré l’événement, ainsi qu’une date d’événement lorsqu’il a été écrit dans S3. Un tel schéma de partitionnement vous permet de copier n’importe quelle fraction des données partitionnées vers Snowflake avec une seule commande COPY. Par exemple, vous pouvez copier des données d’événements par heure, par données, par mois ou par année lorsque vous remplissez initialement les tables.

    Par exemple :

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

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

    Notez que application_a, application_b, location_c, etc., identifient les détails de la source de toutes les données dans le chemin. Les données peuvent être organisées en fonction de la date à laquelle elles ont été écrites. Un répertoire optionnel de 24 heures réduit la quantité de données dans chaque répertoire.

    Note

    S3 transmet une liste de répertoires avec chaque instruction COPY utilisée par Snowflake. Par conséquent, réduire le nombre de fichiers dans chaque répertoire améliore la performance de vos instructions COPY. Vous pouvez même envisager de créer des dossiers par incréments de 10 à 15 minutes par heure.

    Les données d’exemple fourni dans le compartiment S3 utilisent un schéma de partitionnement similaire. Dans une commande COPY, vous indiquerez un chemin de dossier spécifique pour copier les données d’événements.

Création de la base de données, de la table, de l’entrepôt et de la zone de préparation externe

Exécutez les instructions suivantes pour créer une base de données, une table, un entrepôt virtuel et une zone de préparation externe nécessaires pour ce tutoriel. Après avoir terminé le tutoriel, vous pouvez détruire ces objets.

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

Remarques :

  • L’instruction CREATE DATABASE crée une base de données. La base de données comprend automatiquement un schéma nommé « public ».

  • L’instruction USE SCHEMA spécifie une base de données et un schéma actifs pour la session utilisateur actuelle. Le fait de spécifier une base de données vous permet maintenant d’effectuer votre travail dans cette base de données sans avoir à fournir le nom chaque fois qu’il est demandé.

  • L’instruction CREATE TABLE crée une table cible pour les données JSON.

  • L’instruction CREATE WAREHOUSE crée un entrepôt initialement suspendu. L’instruction définit également AUTO_RESUME = true, qui démarre l’entrepôt automatiquement lorsque vous exécutez des instructions SQL qui nécessitent des ressources de calcul. L’instruction USE WAREHOUSE spécifie l’entrepôt que vous avez créé comme entrepôt actif pour la session utilisateur actuelle.

  • L’instruction CREATE STAGE crée une zone de préparation externe qui pointe vers le compartiment S3 contenant le fichier d’exemple pour ce tutoriel.

Copie de données dans la table cible

Exécutez COPY INTO <table> pour charger vos données préparées dans la table cible RAW_SOURCE.

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

La commande copie toutes les nouvelles données du chemin spécifié sur la zone de préparation externe vers la table cible RAW_SOURCE. Dans cet exemple, le chemin spécifié cible les données écrites à la 15e heure (3 PM) du 15 juillet 2016. Notez que Snowflake vérifie la valeur ETag S3 de chaque fichier pour s’assurer qu’il n’est copié qu’une seule fois.

Exécutez une requête SELECT pour vérifier que les données ont bien été copiées.

SELECT * FROM raw_source;
Copy

La requête renvoie le résultat suivant :

+-----------------------------------------------------------------------------------+
| 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

Dans ces données JSON d’exemple, il y a deux événements. Les valeurs clés device_type, et version identifient une source de données et une version pour les événements d’un appareil spécifique.

Données de la requête

Dans cette section, vous explorez les instructions SELECT pour interroger les données JSON.

  1. Récupérez device_type.

    SELECT src:device_type
      FROM raw_source;
    
    Copy

    La requête renvoie le résultat suivant :

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

    La requête utilise la notation src:device_type pour spécifier le nom de la colonne et le nom de l’élément JSON à récupérer. Cette notation est similaire à la notation familière SQL table.column. Snowflake vous permet de spécifier une sous-colonne à l’intérieur d’une colonne parent, que Snowflake dérive dynamiquement de la définition de schéma incorporée dans les données JSON. Pour plus d’informations, reportez-vous à Interrogation de données semi-structurées.

    Note

    Le nom de la colonne n’est pas sensible à la casse, mais les noms des éléments JSON le sont.

  2. Récupérez la valeur device_type sans les guillemets.

    La requête précédente renvoie la valeur des données JSON entre guillemets. Vous pouvez supprimer les guillemets en transformant les données en un type de données spécifique, dans cet exemple une chaîne.

    Cette requête peut également attribuer un nom à la colonne en utilisant un alias.

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

    La requête renvoie le résultat suivant :

    +-------------+
    | DEVICE_TYPE |
    |-------------|
    | server      |
    +-------------+
    
    Copy
  3. Récupérez les clés f répétitives imbriquées dans le tableau d’objets d’événements.

    Les données JSON d’exemple comprennent le tableau events. Chaque objet d’événement dans le tableau a le champ f comme indiqué.

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

    Pour récupérer ces clés imbriquées, vous pouvez utiliser la fonction FLATTEN. La fonction aplatit les événements dans des lignes distinctes.

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

    La requête renvoie le résultat suivant :

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

    Notez que value est une des colonnes que la fonction FLATTEN renvoie. L’étape suivante fournit plus de détails sur l’utilisation de la fonction FLATTEN.

Aplatir des données

FLATTEN est une fonction de table qui produit une vue latérale d’une colonne VARIANT, OBJECT ou ARRAY. Dans cette étape, vous utilisez cette fonction pour explorer différents niveaux d’aplatissement.

Aplatir les objets du tableau dans une colonne de variantes

Vous pouvez aplatir les objets d’événement dans le tableau events dans des lignes distinctes à l’aide de la fonction FLATTEN. La sortie de la fonction comprend une colonne VALUE qui stocke ces événements individuels.

Vous pouvez ensuite utiliser le modificateur LATERAL pour joindre la sortie de la fonction FLATTEN à toute information extérieure à l’objet. Dans cet exemple, les device_type et version.

  1. Interrogez les données de chaque événement :

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

    La requête renvoie le résultat suivant :

    +-------------------------+---------------------+-------------------------------------------------------------------------------+
    | 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. Utilisez une instruction CREATE TABLE AS SELECT pour stocker les résultats de la requête précédente dans une table :

    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

    Interrogez la table résultante.

    SELECT * FROM flattened_source;
    
    Copy

    La requête renvoie le résultat suivant :

    +-------------+---------+-------------------------------------------------------------------------------+
    | 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                                                          |
    |             |         | }                                                                             |
    +-------------+---------+-------------------------------------------------------------------------------+
    

Aplatir les clés des objets dans des colonnes distinctes

Dans l’exemple précédent, vous avez aplati les objets événements du tableau events dans des lignes distinctes. La table flattened_source résultante a conservé la structure de l’événement dans la colonne src du type VARIANT.

L’un des avantages de conserver les objets d’événements dans la colonne src du type VARIANT est que, lorsque le format de l’événement change, il n’est pas nécessaire de recréer et de repeupler ces tables. Mais vous avez également la possibilité de copier des clés individuelles dans l’objet d’événement dans des colonnes typées distinctes, comme le montre la requête suivante.

L’instruction CREATE TABLE AS SELECT suivante crée une nouvelle table nommée events avec les clés de l’objet événement stockées dans des colonnes distinctes. Chaque valeur est convertie vers le type de données correspondant à la valeur à l’aide de deux signes deux-points (::) suivis du type. Si vous ne faites pas de conversion, la colonne choisit le type de données VARIANT par défaut pouvant contenir toute valeur :

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

L’instruction aplatit les données imbriquées dans la clé EVENTS.SRC:V en ajoutant une colonne distincte pour chaque valeur. L’instruction crée une ligne pour chaque paire clé/valeur. La sortie suivante montre les deux premiers enregistrements de la nouvelle table 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

Mettre à jour des données

Jusqu’à présent, dans ce tutoriel, vous avez fait ce qui suit :

  • Copie de données d’événement JSON d’exemple d’un compartiment S3 dans la table RAW_SOURCE et exploration de requêtes simples.

  • Vous avez également exploré la fonction FLATTEN pour aplatir les données JSON et obtenir une représentation relationnelle des données. Par exemple, vous avez extrait des clés d’événements et stocké les clés dans des colonnes distinctes dans une autre table EVENTS.

Au début, le tutoriel explique le scénario d’application où plusieurs sources génèrent des événements et un point de terminaison Web les enregistre dans votre compartiment S3. À mesure que de nouveaux événements sont ajoutés au compartiment S3, vous pouvez utiliser un script pour copier continuellement les nouvelles données dans la table RAW_SOURCE. Mais comment insérer uniquement de nouvelles données d’événement dans la table EVENTS ?

Il existe de nombreuses façons de maintenir la cohérence des données. Cette section présente deux options.

Utiliser les colonnes de clé primaire pour la comparaison

Dans cette section, vous ajoutez une clé primaire à la table EVENTS. La clé primaire garantit alors l’unicité.

  1. Examinez vos données JSON à la recherche de valeurs uniques et qui seraient de bonnes candidates pour une clé primaire. Par exemple, supposons que la combinaison de src:device_type et value:rv puisse être une clé primaire. Ces deux clés JSON correspondent aux colonnes DEVICE_TYPE et RV de la table EVENTS.

    Note

    Snowflake n’applique pas la contrainte de clé primaire. La contrainte sert plutôt de métadonnées identifiant la clé naturelle dans Information Schema.

  2. Ajoutez la contrainte de clé primaire à la table EVENTS :

    ALTER TABLE events ADD CONSTRAINT pk_DeviceType PRIMARY KEY (device_type, rv);
    
    Copy
  3. Insérez un nouvel enregistrement d’événement JSON dans la table 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. Insérez le nouvel enregistrement que vous avez ajouté à la table RAW_SOURCE dans la table EVENTS en se basant sur une comparaison des valeurs de clés primaires :

    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

    L’interrogation de la table EVENTS affiche la ligne ajoutée :

    select * from EVENTS;
    
    Copy

    La requête renvoie le résultat suivant :

    +-------------+---------+---------+----------------------------------------------------------------------+---------------+-------+--------+-----+-------+------+------+------+------+-----+---------------+
    | 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

Utiliser toutes les colonnes pour la comparaison

Si les données JSON ne comportent pas de champs susceptibles d’être des candidats à la clé primaire, vous pourriez comparer toutes les clés JSON répétitives de la table RAW_SOURCE avec les valeurs des colonnes correspondantes de la table EVENTS.

Aucune modification de votre table EVENTS existante n’est requise.

  1. Insérez un nouvel enregistrement d’événement JSON dans la table 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. Insérer le nouvel enregistrement de la table RAW_SOURCE dans la table EVENTS en se basant sur une comparaison des valeurs de clés répétitives :

    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

    L’interrogation de la table EVENTS affiche la ligne ajoutée :

    select * from EVENTS;
    
    Copy

    La requête renvoie le résultat suivant :

    +-------------+---------+---------+----------------------------------------------------------------------+---------------+--------+--------+-------+-------+------+------+------+------+-----+---------------+
    | 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

Félicitations !

Bravo, vous avez terminé le tutoriel.

Points clés du tutoriel

  • Partitionner les données d’événement dans votre compartiment S3 en utilisant des chemins logiques et granulaires vous permet de copier un sous-ensemble des données partitionnées dans Snowflake avec une seule commande.

  • La notation column:key de Snowflake, similaire à la notation familière SQL table.column , vous permet d’interroger efficacement une colonne dans la colonne (c’est-à-dire une sous-colonne), qui est dérivée dynamiquement en fonction de la définition du schéma intégrée dans les données JSON.

  • La fonction FLATTEN vous permet de décomposer des données JSON en colonnes distinctes.

  • Plusieurs options sont disponibles pour mettre à jour les données des tables sur la base de comparaisons avec des fichiers de données préparés.

Didacticiel Nettoyage (facultatif)

Exécutez les commandes DROP <objet> suivantes pour remettre votre système dans son état initial avant de commencer le tutoriel :

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

Détruire la base de données supprime automatiquement toutes les objets de base de données liés, par exemple les tables.