API d'exécution d'instructions : Exécuter du SQL sur des warehouse
Pour accéder aux APIs REST Databricks, vous devez vous authentifier.
Ce tutoriel vous montre comment utiliser l'API Databricks SQL Statement Execution 2.0 pour exécuter des instructions SQL à partir des warehouses Databricks SQL.
Pour afficher la référence de l'API Databricks SQL Statement Execution 2.0, consultez Exécution d'instructions.
Avant de commencer
Avant de start ce tutoriel, assurez-vous d'avoir :
-
Soit la version 0,205 ou supérieure du CLI Databricks ou
curl, comme suit :-
La CLI Databricks est un outil en ligne de commande pour l'envoi et la réception de requêtes et de réponses d'API REST Databricks. Si vous utilisez la CLI Databricks version 0.205 ou supérieure, elle doit être configurée pour l'authentification avec votre workspace Databricks. Consultez Installer ou mettre à jour la CLI Databricks et Authentification pour la CLI Databricks.
Par exemple, pour vous authentifier avec l'authentification par jeton d'accès personnel Databricks, suivez les étapes sur Créer des jetons d'accès personnels pour les utilisateurs de Workspace.
Et puis pour utiliser la CLI Databricks afin de créer un profil de configuration Databricks pour votre jeton d'accès personnel, procédez comme suit :
-
La procédure suivante utilise le CLI Databricks pour créer un profil de configuration Databricks avec le nom DEFAULT. Si vous avez déjà un profil de configuration DEFAULT, cette procédure écrase votre profil de configuration DEFAULT existant.
Pour vérifier si vous avez déjà un profil de configuration DEFAULT, et pour afficher les paramètres de ce profil s'il existe, utilisez l'interface de ligne de commande 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 nom différent pour le profil de configuration.
- Utilisez le CLI Databricks pour créer un profil de configuration Databricks nommé
DEFAULTqui utilise l'authentification par jeton d'accès personnel Databricks. Pour ce faire, exécutez la commande suivante :
databricks configure --profile DEFAULT
-
Pour l'invite Hôte Databricks , saisissez l'URL de votre instance de workspace Databricks, par exemple
https://dbc-a1b2345c-d6e7.cloud.databricks.com. -
Pour l'invite Jeton d'accès personnel , entrez le jeton d'accès personnel Databricks de votre Workspace.
Dans les exemples CLI Databricks de ce didacticiel, notez ce qui suit :
-
Ce tutoriel suppose que vous disposez d'une variable d'environnement
DATABRICKS_SQL_WAREHOUSE_IDsur votre machine de développement locale. Cette variable d'environnement représente l'ID de votre warehouse Databricks SQL. Cet ID est la chaîne de lettres et de chiffres suivant/sql/1.0/warehouses/dans le champ chemin HTTP de votre warehouse. Pour savoir comment obtenir la valeur du chemin HTTP de votre warehouse, consultez Obtenir les détails de connexion pour une Ressource compute Databricks. -
Si vous utilisez le shell de commande Windows au lieu d'un shell de commande pour Unix, Linux ou macOS, remplacez
\par^, et remplacez${...}par%...%. -
Si vous utilisez le Shell de commande Windows au lieu d'un shell de commande pour Unix, Linux ou macOS, dans les déclarations de document JSON, remplacez les
'd'ouverture et de fermeture par", et remplacez les"intérieurs par\". -
curl est un outil de ligne de commande pour envoyer et recevoir des requêtes et des réponses d'API REST. Voir aussi Installer curl. Ou, adaptez les exemples
curlde ce tutoriel pour une utilisation avec des outils similaires tels que HTTPie.Dans les exemples
curlde ce didacticiel, notez ce qui suit :- Au lieu de
--header "Authorization: Bearer ${DATABRICKS_TOKEN}", vous pouvez utiliser un .netrc fichier. Si vous utilisez un fichier.netrc, remplacez--header "Authorization: Bearer ${DATABRICKS_TOKEN}"par--netrc. - Si vous utilisez le shell de commande Windows au lieu d'un shell de commande pour Unix, Linux ou macOS, remplacez
\par^, et remplacez${...}par%...%. - Si vous utilisez le Shell de commande Windows au lieu d'un shell de commande pour Unix, Linux ou macOS, dans les déclarations de document JSON, remplacez les
'd'ouverture et de fermeture par", et remplacez les"intérieurs par\".
De plus, pour les
curlexemples de ce tutoriel, ce tutoriel suppose que vous disposez des variables d'environnement suivantes sur votre machine de développement locale :DATABRICKS_HOST, représentant le nom de l'instance du workspace, par exempledbc-a1b2345c-d6e7.cloud.databricks.com, pour votre Databricks workspace.DATABRICKS_TOKEN, représentant un jeton d'accès personnel Databricks pour votre utilisateur de Workspace Databricks.DATABRICKS_SQL_WAREHOUSE_ID, qui représente l'ID de votre Databricks SQL Warehouse. Cet ID est la chaîne de lettres et de chiffres qui suit/sql/1.0/warehouses/dans le champ HTTP path de votre warehouse. Pour savoir comment obtenir la valeur HTTP path de votre warehouse, consultez Obtenir les détails de connexion pour une ressource de compute Databricks.
- Au lieu de
En tant que bonne pratique de sécurité lorsque vous vous authentifiez avec des outils, des systèmes, des scripts et des applications automatisés, Databricks vous recommande d'utiliser des jetons OAuth.
Si vous utilisez l'authentification par jeton d'accès personnel, Databricks vous recommande d'utiliser les jetons d'accès personnel appartenant aux Service Principal plutôt qu'aux utilisateurs du Workspace. Pour créer des jetons pour les Service Principals, consultez Gérer les jetons pour un Service Principal.
Pour créer un jeton d'accès personnel Databricks, suivez les étapes indiquées dans Créer des jetons d'accès personnels pour les utilisateurs de Workspace.
Databricks déconseille fortement de coder en dur des informations dans vos scripts, car ces informations sensibles peuvent être exposées en texte brut par le biais de systèmes de contrôle de version. Databricks recommande d'utiliser plutôt des approches telles que les variables d'environnement que vous définissez sur votre machine de développement. La suppression de ces informations codées en dur de vos scripts contribue également à rendre ces scripts plus portables.
-
Ce tutoriel suppose que vous disposez également de jq, un processeur en ligne de commande pour interroger les charges utiles de réponse JSON, que l'API Databricks SQL Statement Execution vous renvoie après chaque appel que vous effectuez à l'API Databricks SQL Statement Execution. Voir download jq.
-
Vous devez disposer d'au moins une table sur laquelle vous pouvez exécuter des instructions SQL. Ce tutoriel est basé sur la table
lineitemdu schématpch(également appelé base de données) au sein du cataloguesamples. Si vous n’avez pas accès à ce catalogue, schéma ou cette table depuis votre Workspace, remplacez-les tout au long de ce tutoriel par les vôtres.
Étape 1 : Exécutez une instruction SQL et enregistrez le résultat des données au format JSON
Exécutez la commande suivante, qui effectue les opérations suivantes :
- Utilise le SQL warehouse spécifié, ainsi que le jeton spécifié si vous utilisez
curl, pour interroger trois colonnes à partir des deux premières lignes de la tablelineitemdans le schématcphau sein du cataloguesamples. - Enregistre la charge utile de la réponse au format JSON dans un fichier nommé
sql-execution-response.jsondans le répertoire de travail actuel. - Affiche le contenu du fichier
sql-execution-response.json. - Définit une variable d'environnement locale nommée
SQL_STATEMENT_ID. Cette variable contient l'ID de l'instruction SQL correspondante. Vous pouvez utiliser cet ID d'instruction SQL pour obtenir ultérieurement les informations nécessaires sur cette instruction, comme démontré à l'étape 2. Vous pouvez également consulter cette instruction SQL et obtenir son ID d'instruction dans la section historique des requêtes de la console Databricks SQL, ou en appelant l'API d'historique des requêtes. - Définit une variable d'environnement locale supplémentaire nommée
NEXT_CHUNK_EXTERNAL_LINKqui contient un fragment d'URL d'API pour obtenir le prochain bloc de données JSON. Si les données de réponse sont trop volumineuses, l'API d'exécution des déclarations Databricks SQL fournit la réponse par blocs. Vous pouvez utiliser ce fragment d'URL d'API pour obtenir le prochain bloc de données, ce qui est démontré à l'étape 2. S'il n'y a pas de prochain bloc, alors cette variable d'environnement est définie surnull. - Affiche les valeurs des variables d'environnement
SQL_STATEMENT_IDetNEXT_CHUNK_INTERNAL_LINK.
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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étré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 objetnameetvaluecorrespondant dans le tableauparameters. Untypefacultatif peut également être spécifié, avec la valeur default deSTRINGsi non spécifié.
Databricks recommande vivement que vous utilisiez des parameters à titre de bonne pratique pour vos instructions SQL.
Si vous utilisez l'API Databricks SQL Statement Execution avec une application qui génère du 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 ne prenez pas les mesures appropriées, un attaquant pourrait injecter du code SQL malveillant pour modifier la logique de votre requête initiale, lisant, modifiant ou supprimant ainsi des données sensibles.
Les requêtes paramétrées aident à protéger contre les attaques par injection SQL en traitant les arguments d'entrée séparément du reste de votre code SQL et en interprétant ces arguments comme des valeurs littérales. Les paramètres aident également à la réutilisabilité du code.
-
Par default, toutes les données renvoyées sont au format de tableau JSON, et l'emplacement par default pour tous les résultats de données de l'instruction SQL se trouve 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 renvoyer des résultats de données supérieurs à 25 MiB dans la charge utile de la réponse, un statut d'échec est renvoyé et l'instruction SQL est annulée. Pour les résultats de données supérieurs à 25 MiB, vous pouvez utiliser des Links externes plutôt que d'essayer de les renvoyer dans la charge utile de la réponse, ce qui est 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 directement pris en charge par l'API d'exécution des déclarations Databricks SQL.
-
Par default, après 10 secondes, si l'instruction SQL n'a pas encore terminé son exécution via le warehouse, l'API d'exécution des instructions Databricks SQL renvoie uniquement l'ID de l'instruction SQL et son statut actuel, au lieu du résultat de l'instruction. Pour modifier ce comportement, ajoutez
"wait_timeout"à la requête et définissez-le sur"<x>s", où<x>peut être entre5et50secondes inclus, par exemple"50s". Pour renvoyer immédiatement l'ID de l'instruction SQL et son statut actuel, définissezwait_timeoutsur0s. -
By default, l'instruction SQL continue de s'exécuter si le délai d'expiration est atteint. Pour annuler une instruction SQL si le délai d'expiration est atteint, 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-le sur le nombre d'octets, par exemple1000. -
Pour limiter le nombre de lignes renvoyées, au lieu d'ajouter une clause
LIMITàstatement, vous pouvez ajouter"row_limit"à la requête et le définir sur le nombre de lignes, par exemple"statement":"SELECT * FROM lineitem","row_limit":2. -
Si le résultat est supérieur aux valeurs spécifiées
byte_limitourow_limit, le champtruncatedest défini surtruedans la charge utile de la réponse. -
Pour baliser une instruction pour l'attribution des coûts et le filtrage, ajoutez un tableau
query_tagsà la requête, par exemple"query_tags": [{"key": "team", "value": "finance"}]. Les balises apparaissent danssystem.query.history. Cette fonctionnalité est en Aperçu public. Consultez les Query tags.
Si le résultat de l'instruction est disponible avant la fin du délai d'attente, la réponse est la suivante :
{
"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 ne soit disponible, la réponse se présente comme suit :
{
"statement_id": "00000000-0000-0000-0000-000000000000",
"status": {
"state": "PENDING"
}
}
Si les données de résultat de l'instruction sont trop volumineuses (par exemple dans ce cas, en exécutant SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem LIMIT 300000), les données de résultat sont fragmentées et se présentent comme suit. Notez que "...": "..." indique des résultats 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 : Obtenez l'état d'exécution actuel d'une instruction et le résultat des données 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, le résultat de cette instruction. Si vous oubliez l'ID de l'instruction, vous pouvez l'obtenir dans la section historique des requêtes de la console Databricks SQL, ou en appelant l'API d'historique des requêtes. Par exemple, vous pourriez continuer à interroger cette commande, en vérifiant à chaque fois si l'exécution a réussi.
Pour obtenir le statut d'exécution actuel d'une instruction SQL et, si l'exécution a réussi, le résultat de cette instruction ainsi qu'un fragment d'URL d'API pour obtenir tout fragment suivant de données JSON, exécutez la commande suivante. Cette commande suppose que vous avez une variable d'environnement sur votre machine de développement locale nommée SQL_STATEMENT_ID, qui est définie sur la valeur de l'ID de l'instruction SQL de l'étape précédente. Bien sûr, vous pouvez substituer ${SQL_STATEMENT_ID} dans la commande suivante par l'ID codé en dur de l'instruction SQL.
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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 le NEXT_CHUNK_INTERNAL_LINK est défini sur une valeur autre quenull, vous pouvez l'utiliser pour obtenir le prochain bloc de données, et ainsi de suite, par exemple avec la commande suivante :
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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 continuer à exécuter la commande précédente, encore et encore, pour obtenir le bloc suivant, et ainsi de suite. Notez que dès que le dernier bloc est 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 son statut actuel ou pour récupérer d'autres blocs.
Étape 3 : Récupérer des résultats volumineux à l'aide de liens externes
Cette section présente une configuration facultative qui utilise la disposition EXTERNAL_LINKS pour récupérer de grands ensembles de données. L'emplacement default (disposition) des données de résultat de l'instruction SQL est dans la charge utile de la réponse, mais ces résultats sont limités à 25 Mio. En définissant le disposition sur EXTERNAL_LINKS, la réponse contient des URL que vous pouvez utiliser pour récupérer les morceaux des données de résultats avec le protocole HTTP standard. Les URL pointent vers le DBFS interne de votre workspace, où les fragments de résultats sont temporairement stockés.
Databricks recommande vivement de protéger les URL qui sont renvoyées par la disposition EXTERNAL_LINKS.
Lorsque vous utilisez la disposition EXTERNAL_LINKS, une URL pré-signée à courte durée de vie est générée, qui peut être utilisée pour download les résultats directement depuis Amazon S3. Comme une information d'identification d'accès de courte durée est intégrée dans cette URL pré-signée, vous devriez protéger l'URL.
Étant donné que les URL présignées sont déjà générées avec des identifiants d'accès temporaires intégrés, vous ne devez pas définir un en-tête Authorization dans les requêtes de download.
La fonctionnalité EXTERNAL_LINKS peut être désactivée sur demande en créant un dossier d'assistance. Consultez Support.
Voir aussi Bonnes pratiques de sécurité.
Le format et le comportement de sortie de la charge utile de réponse, une fois définis pour un ID d'instruction SQL particulier, ne peuvent pas être modifiés.
Dans ce mode, l’API vous permet de stocker des données de résultats au format JSON (JSON), au format CSV (CSV) ou au format Apache Arrow (ARROW_STREAM), qui doivent être interrogées séparément avec HTTP. En outre, lorsque vous utilisez ce mode, il n’est pas possible d’intégrer les données de résultat dans la charge utile de la réponse.
La commande suivante démontre l'utilisation de EXTERNAL_LINKS et du format Apache Arrow. Utilisez ce modèle plutôt que la query similaire démontrée à l'étape 1 :
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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 la suivante :
{
"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 ressemble à ceci :
{
"statement_id": "00000000-0000-0000-0000-000000000000",
"status": {
"state": "PENDING"
}
}
Pour obtenir le statut d'exécution actuel de cette instruction et, si l'exécution a réussi, le résultat de cette instruction, exécutez la commande suivante :
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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 suffisamment volumineuse (par exemple, dans ce cas, en exécutant SELECT l_orderkey, l_extendedprice, l_shipdate FROM lineitem sans limite de lignes), la réponse comportera plusieurs blocs, comme dans l'exemple ci-dessous. Notez que "...": "..." indique des résultats 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 download 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 où vous voulez download le fichier. N'incluez pas votre jeton Databricks dans cette commande :
curl "<url-to-result-stored-externally>" \
--output "<path/to/download/the/file/locally>"
Pour download un segment spécifique des résultats d'un contenu en continu, vous pouvez utiliser l'une des options suivantes :
- La valeur
next_chunk_indexde la charge utile de la réponse pour le segment suivant (s'il existe un segment suivant). - Un des index de fragment du manifeste de la charge utile de la réponse pour tout fragment disponible s'il y a plusieurs fragments.
Par exemple, pour obtenir le fragment avec un chunk_index de 10 de la réponse précédente, exécutez la commande suivante :
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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'
L'exécution de la commande précédente renvoie une nouvelle URL pré-signée.
Pour download le segment 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 abouti, exécutez la commande suivante :
- Databricks CLI
- curl
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 Databricks pour l'authentification.
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 des instructions Databricks SQL augmente la sécurité des transferts de données en utilisant le chiffrement de bout en bout de la couche de transport (TLS) et des informations d'identification à courte durée de vie, telles que les URL présignées.
Il existe plusieurs couches dans ce modèle de sécurité. Au niveau de la couche de transport, il est uniquement possible d'appeler l'API Databricks SQL Statement Execution en utilisant TLS 1.2 ou supérieur. Par ailleurs, les appelants de l'API Databricks SQL Statement Execution doivent être authentifiés avec un jeton d'accès personnel Databricks valide qui correspond à un utilisateur ayant le droit d'utiliser Databricks SQL. Cet utilisateur doit avoir l'accès CAN USE pour le SQL Warehouse spécifique utilisé, et l'accès peut être restreint avec les listes d'accès IP. Cela s'applique à toutes les requêtes vers l'API Databricks SQL Statement Execution. En outre, pour l'exécution d'instructions, l'utilisateur authentifié doit disposer d'autorisations 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é par les mécanismes de contrôle d'accès existants dans Unity Catalog ou en utilisant les ACL de table. (Voir Gouvernance des données et de l'IA avec Unity Catalog pour plus de détails.) Cela signifie également que seul l'utilisateur qui exécute une instruction peut effectuer des requêtes d'extraction pour les résultats de l'instruction.
Databricks vous recommande de suivre les meilleures pratiques de sécurité suivantes chaque fois que vous utilisez l'API d'exécution d'instructions Databricks SQL avec la disposition EXTERNAL_LINKS pour récupérer de grands ensembles de données :
- Supprimez l'en-tête d'autorisation Databricks pour les requêtes Amazon S3.
- Protéger les URL pré-signées
- Configurez les restrictions réseau sur les comptes de stockage
- Configurez la journalisation sur les comptes de stockage.
La fonctionnalité EXTERNAL_LINKS peut être désactivée sur demande en créant un dossier d'assistance. Consultez Support.
Supprimer l'en-tête d'autorisation Databricks pour les requêtes Amazon S3
Tous les appels à l’API Databricks SQL Statement Execution qui utilisent curl doivent inclure un en-tête Authorization qui contient les identifiants d’accès Databricks. N'incluez pas cet en-tête Authorization chaque fois que vous download des données depuis Amazon S3. Cet en-tête n’est pas obligatoire et pourrait exposer involontairement vos identifiants d’accès Databricks.
Protéger les URL présignées
Chaque fois que vous utilisez la disposition EXTERNAL_LINKS, une URL présignée de courte durée est générée, que l'appelant peut utiliser pour download les résultats directement depuis Amazon S3 en utilisant TLS. Étant donné qu'un identifiant de courte durée est intégré à cette URL présignée, vous devez protéger l'URL.
Configurer les restrictions réseau sur les comptes de stockage
Chaque fois que vous utilisez la disposition EXTERNAL_LINKS, le client obtiendra des URL pré-signées pour download les résultats de query directement depuis Amazon S3.
Databricks vous recommande d'utiliser les politiques de compartiment S3 pour restreindre l'accès à vos compartiments S3 à des adresses IP fiables et à des Virtual Private Cloud (VPC). Vérifiez que vous disposez des configurations de stockage correctes du compartiment racine du Workspace, et examinez les recommandations de Databricks pour le Virtual Private Cloud (VPC) géré par le client.
Configurez la journalisation sur les comptes de stockage
En plus d'appliquer des restrictions au niveau du réseau sur le compte de stockage sous-jacent, vous pouvez surveiller si quelqu'un tente de contourner ces restrictions en configurant la journalisation d'accès au serveur S3 ou les événements de données AWS CloudTrail ainsi que le monitoring et les alertes appropriées autour d'eux.