Partage via


API d’exécution d’instruction : Exécuter SQL sur les entrepôts

Important

Pour accéder aux API REST Databricks, vous devez vous authentifier.

Ce tutoriel vous montre comment utiliser l’API d’exécution d’instructions Databricks SQL 2.0 pour exécuter des instructions SQL depuis des entrepôts Databricks SQL.

Pour afficher la référence de l’API d’exécution d’instruction SQL Databricks 2.0, consultez d’exécution d’instruction.

Avant de commencer

Avant de commencer ce tutoriel, vérifiez que vous avez les éléments suivants :

  • L’interface CLI Databricks version 0.205 ou version ultérieure, ou curl, comme suit :

    • L’interface CLI Databricks est un outil en ligne de commande utilisé pour l’envoi et la réception des requêtes et réponses de l’API REST Databricks. Si vous utilisez l’interface CLI Databricks version 0.205 ou version ultérieure, elle doit être configurée pour l’authentification auprès de votre espace de travail Azure Databricks. Consultez Installer ou mettre à jour l’interface CLI Databricks et Authentification pour l’interface CLI Databricks.

      Par exemple, pour s'authentifier avec un jeton d'accès personnel Databricks, créez un jeton d'accès personnel comme suit :

      1. Dans votre espace de travail Azure Databricks, cliquez sur votre nom d’utilisateur Azure Databricks dans la barre supérieure, puis sélectionnez Paramètres dans la liste déroulante.
      2. Cliquez sur Développeur.
      3. À côté de Jetons d’accès, cliquez sur Gérer.
      4. Cliquez sur Générer un nouveau jeton.
      5. (Facultatif) Entrez un commentaire qui vous aide à identifier ce jeton à l’avenir et modifiez sa durée de vie par défaut (90 jours). Pour créer un jeton sans durée de vie (non recommandé), laissez vide la zone Durée de vie (en jours).
      6. Cliquez sur Générer.
      7. Copiez le jeton affiché dans un emplacement sécurisé, puis cliquez sur Terminé.

      Remarque

      Veillez à enregistrer le jeton copié dans un emplacement sécurisé. Ne partagez pas votre jeton copié avec d'autres. Si vous le perdez, vous ne pouvez pas régénérer exactement le même. Vous devez donc répéter cette procédure pour créer un jeton. Si vous perdez le jeton copié ou si vous pensez que le jeton a été compromis, Databricks vous recommande vivement de supprimer immédiatement ce jeton de votre espace de travail en cliquant sur l’icône de la corbeille (Révoquer) à côté du jeton de la page Jetons d’accès.

      Si vous n'êtes pas en mesure de créer ou d'utiliser des jetons dans votre espace de travail, cela peut être dû au fait que votre administrateur d'espace de travail a désactivé les jetons ou ne vous a pas donné l'autorisation de créer ou d'utiliser des jetons. Consultez votre administrateur d'espace de travail ou les rubriques suivantes :

      Ensuite, pour utiliser le CLI Databricks afin de créer un profil de configuration Azure Databricks pour votre jeton d'accès personnel, procédez comme suit :

      Remarque

      La procédure suivante utilise l’interface de ligne de commande (CLI) Databricks pour créer un profil de configuration Azure Databricks nommé DEFAULT. Si vous avez déjà un profil de configuration DEFAULT, cette procédure remplace votre profil de configuration DEFAULT existant.

      Pour vérifier si vous avez déjà un profil de configuration DEFAULT et pour voir les paramètres de ce profil s’il existe, utilisez l’interface CLI Databricks pour exécuter la commande databricks auth env --profile DEFAULT.

      Pour créer un profil de configuration avec un nom autre que DEFAULT, remplacez la partie DEFAULT de --profile DEFAULT dans la commande databricks configure suivante par un autre nom de profil de configuration.

      1. Utilisez l’interface CLI Databricks pour créer un profil de configuration Azure Databricks nommé DEFAULT qui utilise l’authentification par jeton d’accès personnel Azure Databricks. Pour ce faire, exécutez la commande suivante :

        databricks configure --profile DEFAULT
        
      2. Pour l’invite Databricks Host , entrez votre URL Azure Databricks par espace de travail, par exemple : https://adb-1234567890123456.7.azuredatabricks.net.

      3. Pour l’invite Jeton d’accès personnel, entrez le jeton d’accès personnel Azure Databricks pour votre espace de travail.

      Dans les exemples d’interface CLI Databricks de ce tutoriel, notez les points suivants :

      • Ce tutoriel suppose que vous disposez d’une variable d’environnement DATABRICKS_SQL_WAREHOUSE_ID sur votre ordinateur de développement local. Cette variable d’environnement représente l’ID de votre entrepôt SQL Databricks. Cet ID est la chaîne de lettres et de chiffres qui suit /sql/1.0/warehouses/ dans le champ chemin HTTP de votre entrepôt. Pour découvrir comment obtenir la valeur de Chemin d’accès HTTP d’un entrepôt, consultez Obtenir des détails de connexion pour une ressource de calcul Azure Databricks.
      • Si vous utilisez l’interpréteur de commandes Windows à la place d’un interpréteur de commandes pour Unix, Linux ou macOS, remplacez \ par ^ et ${...} par %...%.
      • Si vous utilisez l’interpréteur de commandes Windows au lieu d’un interpréteur de commandes pour Unix, Linux ou macOS, dans les déclarations de document JSON, remplacez les éléments d’ouverture et de fermeture ' par ", et remplacez l’élément interne " par \".
    • curl est un outil en ligne de commande utilisé pour l’envoi et la réception des requêtes et réponses de l’API REST. Voir aussi Installer curl. Vous pouvez également adapter les exemples curl de ce tutoriel pour une utilisation avec des outils semblables comme HTTPie.

      Dans les exemples curl ce tutoriel, notez les points suivants :

      • Au lieu de --header "Authorization: Bearer ${DATABRICKS_TOKEN}", vous pouvez utiliser un fichier .netrc. Si vous utilisez un fichier .netrc, remplacez --header "Authorization: Bearer ${DATABRICKS_TOKEN}" par --netrc.
      • Si vous utilisez l’interpréteur de commandes Windows à la place d’un interpréteur de commandes pour Unix, Linux ou macOS, remplacez \ par ^ et ${...} par %...%.
      • Si vous utilisez l’interpréteur de commandes Windows au lieu d’un interpréteur de commandes pour Unix, Linux ou macOS, dans les déclarations de document JSON, remplacez les éléments d’ouverture et de fermeture ' par ", et remplacez l’élément interne " par \".

      En outre, pour les exemples curl de ce tutoriel, nous supposons que vous disposez des variables d’environnement suivantes sur votre ordinateur de développement local :

      Remarque

      En guise de bonne pratique de sécurité, quand vous vous authentifiez avec des outils, systèmes, scripts et applications automatisés, Databricks recommande d’utiliser des jetons d’accès personnels appartenant à des principaux de service et non des utilisateurs de l’espace de travail. Pour créer des jetons d’accès pour des principaux de service, consultez la section Gérer les jetons pour un principal de service.

      Pour créer un jeton d’accès personnel Azure Databricks, effectuez les étapes suivantes :

      1. Dans votre espace de travail Azure Databricks, cliquez sur votre nom d’utilisateur Azure Databricks dans la barre supérieure, puis sélectionnez Paramètres dans la liste déroulante.
      2. Cliquez sur Développeur.
      3. À côté de Jetons d’accès, cliquez sur Gérer.
      4. Cliquez sur Générer un nouveau jeton.
      5. (Facultatif) Entrez un commentaire qui vous aide à identifier ce jeton à l’avenir et modifiez sa durée de vie par défaut (90 jours). Pour créer un jeton sans durée de vie (non recommandé), laissez vide la zone Durée de vie (en jours).
      6. Cliquez sur Générer.
      7. Copiez le jeton affiché dans un emplacement sécurisé, puis cliquez sur Terminé.

      Remarque

      Veillez à enregistrer le jeton copié dans un emplacement sécurisé. Ne partagez pas votre jeton copié avec d'autres. Si vous le perdez, vous ne pouvez pas régénérer exactement le même. Vous devez donc répéter cette procédure pour créer un jeton. Si vous perdez le jeton copié ou si vous pensez que le jeton a été compromis, Databricks vous recommande vivement de supprimer immédiatement ce jeton de votre espace de travail en cliquant sur l’icône de la corbeille (Révoquer) à côté du jeton de la page Jetons d’accès.

      Si vous n'êtes pas en mesure de créer ou d'utiliser des jetons dans votre espace de travail, cela peut être dû au fait que votre administrateur d'espace de travail a désactivé les jetons ou ne vous a pas donné l'autorisation de créer ou d'utiliser des jetons. Consultez votre administrateur d'espace de travail ou les rubriques suivantes :

      Avertissement

      Databricks déconseille fortement de coder en dur des informations sensibles dans vos scripts, car ces informations peuvent ensuite être exposées en texte brut par des systèmes de gestion des versions. À la place, Databricks recommande d’utiliser d’autres approches, comme celle consistant à définir des variables d’environnement sur l’ordinateur de développement. La suppression des informations codées en dur dans vos scripts contribue également à améliorer la portabilité de ces scripts.

  • Ce tutoriel suppose également que vous disposez de jq, un processeur de ligne de commande pour l’interrogation des charges utiles de réponse JSON, que l’API d’exécution d’instructions SQL Databricks vous renvoie après chaque appel que vous effectuez à l’API d’exécution d’instructions SQL Databricks. Consultez Télécharger jq.

  • Vous devez disposez d’au moins une table sur laquelle vous pouvez exécuter des instructions SQL. Ce tutoriel est basé sur la table lineitem dans le schéma tpch (également appelé base de données) dans le catalogue samples. Si vous n’avez pas accès à ce catalogue, à ce schéma ou à cette table à partir de votre espace de travail, remplacez-les par les vôtres tout au long de ce tutoriel.

Étape 1 : Exécuter une instruction SQL et enregistrer les données de résultat au format JSON

Exécutez la commande suivante, qui effectue ces actions :

  1. Utilise l’entrepôt SQL spécifié, avec le jeton spécifié si vous utilisez curl, pour interroger trois colonnes à partir des deux premières lignes de la table lineitem dans le schéma tcph dans le catalogue samples.
  2. Enregistre la charge utile de la réponse au format JSON dans un fichier nommé sql-execution-response.json dans le répertoire de travail actif.
  3. Affiche le contenu du fichier sql-execution-response.json.
  4. Définit une variable d’environnement locale nommée SQL_STATEMENT_ID. Cette variable contient l’ID de l’instruction SQL correspondante. Vous pourrez utiliser cet ID d’instruction SQL pour obtenir des informations sur cette instruction ultérieurement si nécessaire, comme expliqué à l’étape 2. Vous pouvez également afficher cette instruction SQL et obtenir son ID d’instruction à partir de la section de l’historique des requêtes dans la console SQL Databricks, ou en appelant l’API Historique des requêtes.
  5. Définit une autre variable d’environnement locale nommée NEXT_CHUNK_EXTERNAL_LINK qui contient un fragment d’URL d’API permettant d’obtenir le bloc de données JSON suivant. Si les données de réponse sont trop volumineuses, l’API d’exécution d’instructions Databricks SQL fournit la réponse en blocs. Vous pouvez utiliser ce fragment d’URL d’API pour obtenir le bloc de données suivant, comme expliqué à l’étape 2. Quand il n’y a plus de bloc de données à suivre, cette variable d’environnement est définie sur null.
  6. Affiche les valeurs des variables d’environnement SQL_STATEMENT_ID et NEXT_CHUNK_INTERNAL_LINK.

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

Dans la requête précédente :

  • Les requêtes paramétrisées se composent du nom de chaque paramètre de requête précédé d’un deux-points (par exemple, :extended_price) avec un objet name et value correspondant dans le tableau parameters. Une option facultative type peut également être spécifiée, avec la valeur par défaut STRING si elle n’est pas spécifiée.

    Avertissement

    Databricks vous recommande vivement d’utiliser des paramètres comme meilleure pratique pour vos instructions SQL.

    Si vous utilisez l’API d’exécution d’instruction SQL Databricks avec une application qui génère SQL dynamiquement, cela peut entraîner des attaques par injection SQL. Par exemple, si vous générez du code SQL basé sur les sélections d’un utilisateur dans une interface utilisateur et que vous ne prenez pas les mesures appropriées, un attaquant peut injecter du code SQL malveillant pour modifier la logique de votre requête initiale, ainsi lire, modifier ou supprimer des données sensibles.

    Les requêtes paramétrables aident à se protéger contre les attaques par injections SQL en gérant les arguments d’entrée séparément du reste de votre code SQL et en interprétant ces arguments en tant que valeurs littérales. Les paramètres aident également à réutiliser le code.

  • Par défaut, toutes les données retournées sont au format de tableau JSON, et les données de résultat de l’instruction SQL sont retournées par défaut dans la charge utile de la réponse. Pour rendre ce comportement explicite, ajoutez "format":"JSON_ARRAY","disposition":"INLINE" à la charge utile de la requête. Si vous tentez de retourner des données de résultat de plus de 25 Mio dans la charge utile de la réponse, un état d’échec est retourné et l’instruction SQL est annulée. Pour les résultats de données supérieurs à 25 Mio, vous pouvez utiliser des liens externes au lieu d’essayer de les retourner dans la charge utile de réponse, comme illustré à l’étape 3.

  • La commande stocke le contenu de la charge utile de la réponse dans un fichier local. Le stockage de données local n’est pas pris en charge directement par l’API d’exécution d’instructions Databricks SQL.

  • Par défaut, après 10 secondes, si l’instruction SQL n’a pas encore terminé son exécution via l’entrepôt, l’API d’exécution d’instruction SQL retourne uniquement l’ID de l’instruction SQL et son état actuel, au lieu du résultat de l’instruction. Pour modifier ce comportement, ajoutez "wait_timeout" à la charge utile de la requête et définissez le sur "<x>s", où <x> est compris entre 5 et 50 secondes (inclus), par exemple "50s". Pour retourner immédiatement l’ID de l’instruction SQL et son état actuel, définissez wait_timeout sur 0s.

  • Par défaut, l’instruction SQL continue de s’exécuter après l’expiration du délai d’attente. Pour annuler une instruction SQL à l’expiration du délai d’attente, ajoutez "on_wait_timeout":"CANCEL" à la charge utile de la requête.

  • Pour limiter le nombre d’octets retournés, ajoutez "byte_limit" à la requête et définissez-la sur le nombre d’octets, par exemple 1000.

  • Pour limiter le nombre de lignes retournées, au lieu d’ajouter une clause LIMIT à statement, vous pouvez ajouter "row_limit" à la requête et la définir sur le nombre de lignes, par exemple "statement":"SELECT * FROM lineitem","row_limit":2.

  • Si le résultat est supérieur à l' byte_limit ou row_limitspécifié, le champ truncated est défini sur true dans la charge utile de réponse.

Si le résultat de l’instruction est disponible avant l’expiration du délai d’attente, la réponse se présente comme ceci :

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

Si le délai d’attente expire avant que le résultat de l’instruction soit disponible, la réponse se présente ainsi :

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

Si les données de résultat de l’instruction sont trop volumineuses (ce qui est le cas en exécutant SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem LIMIT 300000, par exemple), elles sont retournées en plusieurs blocs de la façon suivante. Notez que "...": "..." signale des résultats qui ont été omis ici par souci de concision :

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

Étape 2 : Obtenir l’état d’exécution actuel d’une instruction et les données de résultat au format JSON

Vous pouvez utiliser l’ID d’une instruction SQL pour obtenir l’état d’exécution actuel de cette instruction et, si l’exécution a réussi, obtenir aussi le résultat de l’instruction. Si vous ne vous souvenez pas de l’ID de l’instruction, vous pouvez le trouver dans la section de l’historique des requêtes dans la console SQL Databricks, ou en appelant l’API Historique des requêtes. Par exemple, vous pouvez continuer à interroger cette commande, en vérifiant à chaque fois si l’exécution a réussi.

Pour obtenir l’état d’exécution actuel d’une instruction SQL et, si l’exécution a réussi, obtenir aussi le résultat de cette instruction et un fragment d’URL d’API permettant d’obtenir le bloc de données JSON suivant, exécutez la commande suivante. Cette commande suppose que la variable d’environnement SQL_STATEMENT_ID sur votre ordinateur de développement local est définie sur la valeur de l’ID de l’instruction SQL obtenue à l’étape précédente. Bien sûr, vous pouvez remplacer ${SQL_STATEMENT_ID} dans la commande suivante par l’ID codé en dur de l’instruction SQL.

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

Si NEXT_CHUNK_INTERNAL_LINK est défini sur une valeur non null, vous pouvez l’utiliser pour obtenir le bloc de données suivant, et tous les autres blocs, en exécutant par exemple la commande suivante :

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

Vous pouvez réexécuter la commande précédente autant de fois que nécessaire pour obtenir chacun des blocs de données suivants. Notez que dès que le dernier bloc de données a été récupéré, l’instruction SQL est fermée. Après cette fermeture, vous ne pouvez plus utiliser l’ID de cette instruction pour obtenir l’état actuel de l’instruction ou extraire d’autres blocs de données.

Cette section illustre une configuration facultative qui utilise la disposition EXTERNAL_LINKS pour récupérer des jeux de données volumineux. L’emplacement par défaut (disposition) des données de résultat de l’instruction SQL se trouve dans la charge utile de réponse, mais ces résultats sont limités à 25 Mio. En définissant disposition sur EXTERNAL_LINKS, la réponse contient des URL que vous pouvez utiliser pour extraire les blocs des données des résultats avec HTTP standard. Les URL pointent vers le DBFS interne de votre espace de travail, où les blocs de résultats sont stockés temporairement.

Avertissement

Databricks vous recommande vivement de protéger les URL et les jetons retournés par la disposition EXTERNAL_LINKS.

Lorsque vous utilisez la disposition EXTERNAL_LINKS, une URL de signature d’accès partagé (SAP) est générée, qui peut être utilisée pour télécharger les résultats directement à partir du stockage Azure. Étant donné qu’un jeton SAS à courte durée est incorporé dans cette URL SAS, vous devez protéger à la fois l’URL SAS et le jeton SAS.

Étant donné que les URL SAS sont déjà générées avec des jetons SAS temporaires incorporés, vous ne devez pas définir d’en-tête Authorization dans les demandes de téléchargement.

La disposition EXTERNAL_LINKS peut être désactivée sur demande en créant un cas de support.

Voir aussi Bonnes pratiques de sécurité.

Notes

Une fois que le format et le comportement de sortie de la charge utile de la réponse ont été définis pour un ID d’instruction SQL particulier, ils ne peuvent plus être modifiés.

Dans ce mode, l’API vous permet de stocker les données de résultat au format JSON (JSON), au format CSV (CSV) ou au format Apache Arrow (ARROW_STREAM) qui doit être interrogé séparément avec HTTP. Par ailleurs, dans ce mode, il n’est pas possible d’inclure les données de résultat dans la charge utile de la réponse.

La commande suivante illustre l’utilisation de EXTERNAL_LINKS et du format Apache Arrow. Utilisez ce modèle au lieu de la requête similaire illustrée à l’étape 1 :

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

La réponse est comme suit :

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

Si la requête expire, la réponse se présente comme suit :

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

Pour obtenir l’état d’exécution actuel de cette instruction et, si l’exécution a réussi, obtenir aussi le résultat de l’instruction, exécutez la commande suivante :

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

Si la réponse est volumineuse (ce qui est le cas en exécutant SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem sans limite de ligne, par exemple), la réponse est retournée en plusieurs blocs de données, comme dans l’exemple suivant ci-dessous. Notez que "...": "..." signale des résultats qui ont été omis ici par souci de concision :

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

Pour télécharger les résultats du contenu stocké, vous pouvez exécuter la commande curl suivante, en utilisant l’URL de l’objet external_link et en spécifiant l’emplacement où vous souhaitez télécharger le fichier. N’incluez pas le jeton Azure Databricks dans cette commande :

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

Pour télécharger un segment spécifique des résultats d’un contenu diffusé en continu, vous pouvez utiliser l’une des options suivantes :

  • Valeur next_chunk_index de la charge utile de réponse pour le bloc suivant (s’il existe un bloc suivant).
  • L’un des index de bloc du manifeste de charge utile de réponse pour tout bloc disponible s’il existe plusieurs blocs.

Par exemple, pour obtenir le bloc de données avec la valeur chunk_index 10 de la réponse précédente, exécutez la commande suivante :

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

Remarque

L’exécution de la commande précédente retourne une nouvelle URL SAS.

Pour télécharger le bloc stocké, utilisez l’URL dans l’objet external_link.

Pour plus d’informations sur le format Apache Arrow, consultez :

Étape 4 : Annuler l’exécution d’une instruction SQL

Si vous devez annuler une instruction SQL qui n’a pas encore réussi, exécutez la commande suivante :

Interface CLI Databricks

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

Remplacez <profile-name> par le nom de votre profil de configuration Azure Databricks pour l’authentification.

curl

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

Bonnes pratiques de sécurité

L’API d’exécution d’instruction Databricks SQL augmente la sécurité des transferts de données en utilisant le chiffrement TLS (Transport Layer Security) de bout en bout et des informations d’identification de courte durée telles que des jetons SAS.

Ce modèle de sécurité comporte plusieurs couches. Au niveau de la couche de transport, il est possible de communiquer avec l’API d’exécution d’instructions Databricks SQL seulement en utilisant TLS 1.2 ou ultérieur. En outre, les appelants de l’API d’exécution d’instruction Databricks SQL doivent être authentifiés avec un jeton d’accès personnel Azure Databricks valide, un jeton d’accès OAuth ou un jeton Microsoft Entra ID (anciennement Azure Active Directory) qui mappe à un utilisateur ayant le droit d’utiliser Databricks SQL. Cet utilisateur doit disposer d’un accès PEUT UTILISER pour l’entrepôt SQL spécifique utilisé, et l’accès peut être restreint avec des listes d’accès IP. Cela s’applique à toutes les requêtes adressées à l’API d’exécution d’instruction Databricks SQL. En outre, pour exécuter des instructions, l’utilisateur authentifié doit disposer de l’autorisation sur les objets de données (tels que les tables, les vues et les fonctions) qui sont utilisés dans chaque instruction. Ceci est appliqué via des mécanismes de contrôle d’accès existants dans Unity Catalog ou en utilisant des listes de contrôle d’accès aux tables. (Pour plus d’informations, consultez Gouvernance des données avec Unity Catalog.) Cela signifie également que seul l’utilisateur qui exécute une instruction peut effectuer des demandes d’extraction pour les résultats de l’instruction.

Databricks recommande les meilleures pratiques de sécurité suivantes chaque fois que vous utilisez l’API d’exécution d’instructions SQL Databricks avec la disposition EXTERNAL_LINKS pour récupérer des jeux de données volumineux :

  • Supprimer l’en-tête d’autorisation Databricks pour les demandes de stockage Azure
  • Protéger les URL SAS et les jetons SAS

La disposition EXTERNAL_LINKS peut être désactivée sur demande en créant un cas de support. Pour faire cette requête, contactez l’équipe de votre compte Azure Databricks.

Supprimer l’en-tête d’autorisation Databricks pour les demandes de stockage Azure

Tous les appels à l’API d’exécution d’instruction Databricks SQL utilisant curl doivent inclure un en-tête Authorization qui contient les informations d’identification d’accès Azure Databricks. N’incluez pas cet en-tête Authorization chaque fois que vous téléchargez des données à partir du stockage Azure. Cet en-tête n’est pas obligatoire et peut exposer involontairement vos informations d’identification d’accès Azure Databricks.

Protéger les URL SAS et les jetons SAS

Chaque fois que vous utilisez la dispositionEXTERNAL_LINKS , une URL SAS à courte durée est générée, que l’appelant peut utiliser pour télécharger les résultats directement à partir du stockage Azure à l’aide de TLS. Étant donné qu’un jeton SAS à courte durée est incorporé dans cette URL SAS, vous devez protéger à la fois l’URL SAS et le jeton SAS.