Pilote SQL Databricks pour Node.js
Le pilote Databricks SQL pour Node.js est une bibliothèque Node.js permettant d’utiliser du code JavaScript pour exécuter des commandes SQL sur des ressources de calcul Azure Databricks.
Spécifications
Machine de développement exécutant Node.js, version 14 ou ultérieure. Pour imprimer la version installée de Node.js, exécutez la commande
node -v
. Pour installer et utiliser différentes versions de Node.js, vous pouvez utiliser des outils tels que Node Version Manager (nvm).Gestionnaire de package Node (
npm
). Les versions ultérieures de Node.js incluent déjànpm
. Pour vérifier sinpm
est installé, exécutez la commandenpm -v
. Pour installernpm
si nécessaire, vous pouvez suivre des instructions telles que celles du téléchargement et de l’installation de npm.Le package @databricks/sql venant de npm. Pour installer le package
@databricks/sql
dans votre projet Node.js comme dépendance, utiliseznpm
pour exécuter la commande suivante à partir du même répertoire que celui de votre projet :npm i @databricks/sql
Si vous souhaitez installer et utiliser TypeScript dans votre projet Node.js comme
devDependencies
, utiliseznpm
pour exécuter les commandes suivantes à partir du même répertoire que celui de votre projet :npm i -D typescript npm i -D @types/node
Cluster ou entrepôt SQL existant.
Les valeurs Nom d’hôte du serveur et Chemin HTTP pour le cluster ou l’entrepôt SQL existant.
Authentification
Le pilote Databricks SQL pour Node.js prend en charge les types d’authentification Azure Databricks suivants :
- Authentification par jeton d’accès personnel Databricks
- Authentification par jeton Microsoft Entra ID
- Authentification OAuth machine à machine (M2M)
- Authentification utilisateur à machine (U2M) OAuth
Le pilote Databricks SQL pour Node.js ne prend pas encore en charge les types d’authentification Azure Databricks suivants :
- Authentification par identités managées Azure
- Authentification du principal de service MS Entra
- Authentification Azure CLI
Remarque
Une bonne pratique de sécurité est de ne pas coder en dur les valeurs de variable de connexion dans votre code. Au lieu de cela, vous devez récupérer ces valeurs de variable de connexion à partir d’un emplacement sécurisé. Par exemple, les extrait de code et exemples de cet article utilisent des variables d’environnement.
Authentification par jeton d’accès personnel Databricks
Pour utiliser Databricks SQL Driver pour Node.js avec l’authentification, vous devez d’abord créer un jeton d’accès personnel Azure Databricks. Pour plus d’informations sur cette étape, consultez les jetons d’accès personnels Azure Databricks pour les utilisateurs de l’espace de travail.
Pour authentifier le pilote Databricks SQL pour Node.js, utilisez l’extrait de code suivant. Cet extrait suppose que vous avez défini les variables d’environnement suivantes :
DATABRICKS_SERVER_HOSTNAME
réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.DATABRICKS_HTTP_PATH
, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.DATABRICKS_TOKEN
, réglé sur le jeton d’accès personnel Azure Databricks.
Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
const token = process.env.DATABRICKS_TOKEN;
if (!token || !serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"personal access token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
// ...
TypeScript
import { DBSQLClient } from "@databricks/sql";
const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string = process.env.DATABRICKS_HTTP_PATH || '';
const token: string = process.env.DATABRICKS_TOKEN || '';
if (token == '' || serverHostname == '' || httpPath == '') {
throw new Error("Cannot find Server Hostname, HTTP Path, or personal access token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
// ...
Authentification utilisateur à machine (U2M) OAuth
Les versions 1.8.0 et ultérieures du pilote Databricks SQL pour Node.js prennent en charge l’authentification utilisateur à machine (U2M) OAuth.
Pour authentifier le pilote Databricks SQL pour Node.js avec l’authentification U2M OAuth, utilisez l’extrait de code suivant. Cet extrait suppose que vous avez défini les variables d’environnement suivantes :
DATABRICKS_SERVER_HOSTNAME
réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.DATABRICKS_HTTP_PATH
, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.
Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
if (!serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname or HTTP Path. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME " +
"and DATABRICKS_HTTP_PATH.");
}
const client = new DBSQLClient();
const connectOptions = {
authType: "databricks-oauth",
useDatabricksOAuthInAzure: true,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
// ...
TypeScript
import { DBSQLClient } from "@databricks/sql";
const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string = process.env.DATABRICKS_HTTP_PATH || '';
if (serverHostname == '' || httpPath == '') {
throw new Error("Cannot find Server Hostname or HTTP Path. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME " +
"and DATABRICKS_HTTP_PATH.");
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
authType: "databricks-oauth",
useDatabricksOAuthInAzure: true,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
// ...
Authentification OAuth machine à machine (M2M)
Les versions 1.8.0 et ultérieures du pilote Databricks SQL pour Node.js prennent en charge l’authentification machine à machine (U2M) OAuth.
Pour utiliser le pilote Databricks SQL pour Node.js avec l’authentification M2M OAuth, vous devez effectuer les opérations suivantes :
Créez un principal de service Azure Databricks dans votre espace de travail Azure Databricks et créez un secret OAuth pour ce principal de service.
Pour créer le principal de service et son secret OAuth, consultez Authentifier l’accès à Azure Databricks avec un principal de service à l’aide d’OAuth (OAuth M2M). Notez la valeur de l’UUID ou de l’ID de l’application du principal de service, ainsi que la valeur du secret OAuth du principal de service.
Accordez au principal de service l’accès à votre cluster ou entrepôt. Consultez Autorisations de calcul ou Gérer un entrepôt SQL.
Pour authentifier le pilote Databricks SQL pour Node.js, utilisez l’extrait de code suivant. Cet extrait suppose que vous avez défini les variables d’environnement suivantes :
DATABRICKS_SERVER_HOSTNAME
réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.DATABRICKS_HTTP_PATH
, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.DATABRICKS_CLIENT_ID
, est fixé à la valeur de l’UUID ou de l’ID de l’application du principal de service.DATABRICKS_CLIENT_SECRET
, définie sur la valeur Secret du secret OAuth du principal de service.
Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
const clientId = process.env.DATABRICKS_CLIENT_ID;
const clientSecret = process.env.DATABRICKS_CLIENT_SECRET;
if (!serverHostname || !httpPath || !clientId || !clientSecret) {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"service principal ID or secret. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, DATABRICKS_CLIENT_ID, and " +
"DATABRICKS_CLIENT_SECRET.");
}
const client = new DBSQLClient();
const connectOptions = {
authType: "databricks-oauth",
useDatabricksOAuthInAzure: true,
host: serverHostname,
path: httpPath,
oauthClientId: clientId,
oauthClientSecret: clientSecret
};
client.connect(connectOptions)
// ...
TypeScript
import { DBSQLClient } from "@databricks/sql";
const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string = process.env.DATABRICKS_HTTP_PATH || '';
const clientId: string = process.env.DATABRICKS_CLIENT_ID || '';
const clientSecret: string = process.env.DATABRICKS_CLIENT_SECRET || '';
if (serverHostname == '' || httpPath == '' || clientId == '' || clientSecret == '') {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"service principal ID or secret. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, DATABRICKS_CLIENT_ID, and " +
"DATABRICKS_CLIENT_SECRET.");
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
authType: "databricks-oauth",
useDatabricksOAuthInAzure: true,
host: serverHostname,
path: httpPath,
oauthClientId: clientId,
oauthClientSecret: clientSecret
};
client.connect(connectOptions)
// ...
Authentification par jeton Microsoft Entra ID
Pour utiliser le pilote Databricks SQL pour Node.js avec l’authentification par jeton Microsoft Entra ID, vous devez fournir le pilote Databricks SQL pour Node.js avec le jeton Microsoft Entra ID. Pour créer un jeton d’accès Microsoft Entra ID, effectuez ce qui suit :
- Vous pouvez utiliser l’interface utilisateur Azure CLI pour un utilisateur Azure Databricks. Consultez Obtenir des jetons Microsoft Entra ID pour les utilisateurs avec Azure CLI.
- Pour un principal de service Microsoft Entra ID, consultez Obtenir un jeton d’accès Microsoft Entra ID avec Azure CLI. Pour créer un principal de service géré par Microsoft Entra ID, consultez Gérer les principaux de service.
Les jetons Microsoft Entra ID ont une durée de vie par défaut d’environ une heure. Pour créer un jeton Microsoft Entra ID, répétez ce processus.
Pour authentifier le pilote Databricks SQL pour Node.js, utilisez l’extrait de code suivant. Cet extrait suppose que vous avez défini les variables d’environnement suivantes :
DATABRICKS_SERVER_HOSTNAME
réglé sur la valeur Nom d'hôte de serveur de votre cluster ou entrepôt SQL.DATABRICKS_HTTP_PATH
, réglé sur la valeur Chemin HTTP de votre cluster ou entrepôt SQL.DATABRICKS_TOKEN
, défini sur le jeton Microsoft Entra ID.
Pour définir des variables d’environnement, consultez la documentation de votre système d’exploitation.
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
const token = process.env.DATABRICKS_TOKEN;
if (!token || !serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"<ms-entra-id> token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
// ...
TypeScript
import { DBSQLClient } from "@databricks/sql";
const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string = process.env.DATABRICKS_HTTP_PATH || '';
const token: string = process.env.DATABRICKS_TOKEN || '';
if (token == '' || serverHostname == '' || httpPath == '') {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"<ms-entra-id> token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
// ...
Interroger des données
L’exemple de code suivant montre comment appeler le pilote Databricks SQL pour Node.js pour exécuter une requête SQL de base sur une ressource de calcul Azure Databricks. Cette commande retourne les deux premières lignes de la table trips
dans le schéma nyctaxi
du catalogue samples
.
Remarque
L’exemple de code suivant montre comment utiliser un jeton d’accès personnel Azure Databricks pour l’authentification. Pour utiliser plutôt d’autres types d’authentification Azure Databricks, consultez l’article Authentification.
Cet exemple de code récupère les valeurs des variables de connexion token
, server_hostname
et http_path
à partir d’un ensemble de variables d’environnement Azure Databricks. Ces variables d’environnement ont les noms de variables d’environnement suivantes :
DATABRICKS_TOKEN
, qui représente votre jeton d’accès personnel Azure Databricks à partir des exigences.DATABRICKS_SERVER_HOSTNAME
, qui représente la valeur Nom d’hôte du serveur issue des exigences.DATABRICKS_HTTP_PATH
, qui représente la valeur Chemin HTTP issue des exigences.
Vous pouvez utiliser d’autres approches pour récupérer ces valeurs de variable de connexion. L’utilisation de variables d’environnement n’est qu’une seule approche parmi plusieurs.
L’exemple de code suivant montre comment appeler le connecteur Databricks SQL pour Node.js afin d’exécuter une commande SQL de base sur un cluster ou un entrepôt SQL. Cette commande retourne les deux premières lignes de la table trips
.
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const token = process.env.DATABRICKS_TOKEN;
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
if (!token || !serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname, HTTP Path, or personal access token. " +
"Check the environment variables DATABRICKS_TOKEN, " +
"DATABRICKS_SERVER_HOSTNAME, and DATABRICKS_HTTP_PATH.");
}
const client = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
.then(async client => {
const session = await client.openSession();
const queryOperation = await session.executeStatement(
'SELECT * FROM samples.nyctaxi.trips LIMIT 2',
{
runAsync: true,
maxRows: 10000 // This option enables the direct results feature.
}
);
const result = await queryOperation.fetchAll();
await queryOperation.close();
console.table(result);
await session.close();
await client.close();
})
.catch((error) => {
console.error(error);
});
TypeScript
import { DBSQLClient } from '@databricks/sql';
import IDBSQLSession from '@databricks/sql/dist/contracts/IDBSQLSession';
import IOperation from '@databricks/sql/dist/contracts/IOperation';
const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string = process.env.DATABRICKS_HTTP_PATH || '';
const token: string = process.env.DATABRICKS_TOKEN || '';
if (serverHostname == '' || httpPath == '' || token == '') {
throw new Error("Cannot find Server Hostname, HTTP Path, or personal access token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
host: serverHostname,
path: httpPath,
token: token
};
client.connect(connectOptions)
.then(async client => {
const session: IDBSQLSession = await client.openSession();
const queryOperation: IOperation = await session.executeStatement(
'SELECT * FROM samples.nyctaxi.trips LIMIT 2',
{
runAsync: true,
maxRows: 10000 // This option enables the direct results feature.
}
);
const result = await queryOperation.fetchAll();
await queryOperation.close();
console.table(result);
await session.close();
client.close();
})
.catch((error) => {
console.error(error);
});
Sortie :
┌─────────┬─────┬────────┬───────────┬───────┬─────────┬────────┬───────┬───────┬────────┬────────┬────────┐
│ (index) │ _c0 │ carat │ cut │ color │ clarity │ depth │ table │ price │ x │ y │ z │
├─────────┼─────┼────────┼───────────┼───────┼─────────┼────────┼───────┼───────┼────────┼────────┼────────┤
│ 0 │ '1' │ '0.23' │ 'Ideal' │ 'E' │ 'SI2' │ '61.5' │ '55' │ '326' │ '3.95' │ '3.98' │ '2.43' │
│ 1 │ '2' │ '0.21' │ 'Premium' │ 'E' │ 'SI1' │ '59.8' │ '61' │ '326' │ '3.89' │ '3.84' │ '2.31' │
└─────────┴─────┴────────┴───────────┴───────┴─────────┴────────┴───────┴───────┴────────┴────────┴────────┘
Sessions
Toutes les méthodes IDBSQLSession
qui renvoient des objets IOperation
dans la référence API ont les paramètres communs suivants qui affectent leur comportement :
- Le réglage
runAsync
surtrue
démarre le mode asynchrone. Les méthodesIDBSQLSession
mettent les opérations dans la file d’attente et reviennent le plus rapidement possible. L'état actuel de l'objet renvoyéIOperation
peut varier et le client est responsable de vérifier son état avant d'utiliser l'objet renvoyéIOperation
. Consultez Opérations. La définitionrunAsync
surfalse
signifie que les méthodesIDBSQLSession
attendent la fin des opérations. Databricks recommande de toujours définirrunAsync
surtrue
. - La définition de
maxRows
comme une valeur non nulle permet d’obtenir des résultats directs. Avec des résultats directs, le serveur essaie d'attendre la fin des opérations, puis récupère une partie des données. En fonction de la quantité de travail que le serveur a pu effectuer dans le délai défini, les objetsIOperation
reviennent dans un état intermédiaire plutôt que dans un état en attente. Très souvent, toutes les métadonnées et résultats de requête sont renvoyés dans une seule requête adressée au serveur. Le serveur l'utilisemaxRows
pour déterminer le nombre d'enregistrements qu'il peut renvoyer immédiatement. Cependant, le morceau réel peut être d’une taille différente ; voirIDBSQLSession.fetchChunk
. Les résultats directs sont activés par défaut. Databricks recommande de ne pas désactiver les résultats directs.
Opérations
Comme décrit dans Sessions, IOperation
les objets renvoyés par les méthodes de session IDBSQLSession
dans la référence API ne sont pas entièrement renseignés. L'opération de serveur associée peut être toujours en cours, par exemple en attendant le démarrage de l'entrepôt SQL Databricks, en exécutant la requête ou en récupérant les données. La classe IOperation
cache ces détails aux utilisateurs. Par exemple, des méthodes telles que fetchAll
, fetchChunk
et getSchema
attendent en interne la fin des opérations, puis renvoient les résultats. Vous pouvez utiliser la méthode IOperation.finished()
pour attendre explicitement la fin des opérations. Ces méthodes nécessitent un rappel périodiquement appelé en attendant la fin des opérations. Définir l'option progress
sur true
tente de demander des données de progression supplémentaires au serveur et de les transmettre à ce rappel.
Les méthodes close
et cancel
peuvent être appelées à tout moment. Lorsqu'ils sont appelés, ils invalident immédiatement l'objet IOperation
; tous les appels en attente tels que fetchAll
, fetchChunk
et getSchema
sont immédiatement annulés et une erreur est renvoyée. Dans certains cas, l'opération du serveur peut être déjà terminée et la méthode cancel
affecte uniquement le client.
La méthode fetchAll
appelle fetchChunk
en interne et collecte toutes les données dans un tableau. Bien que cela soit pratique, cela peut provoquer des erreurs de mémoire insuffisante lorsqu'il est utilisé sur de grands ensembles de données. les options fetchAll
sont généralement transmises à fetchChunk
.
Récupérer des morceaux de données
La récupération de blocs de données utilise le modèle de code suivant :
do {
const chunk = await operation.fetchChunk();
// Process the data chunk.
} while (await operation.hasMoreRows());
La méthode fetchChunk
de la référence API traite les données en petites portions pour réduire la consommation de mémoire. fetchChunk
attend d'abord que les opérations se terminent si elles ne sont pas déjà terminées, puis appelle un rappel pendant le cycle d'attente, puis récupère le bloc de données suivant.
Vous pouvez utiliser l'option maxRows
pour spécifier la taille de morceau souhaitée. Cependant, le morceau renvoyé peut avoir une taille différente, plus petite ou même parfois plus grande. fetchChunk
ne tente pas de pré-extraire les données en interne, afin de les découper en parties demandées. Il envoie l'option maxRows
au serveur et renvoie tout ce que le serveur renvoie. Ne confondez pas cette option maxRows
avec celle de IDBSQLSession
. maxRows
passé à fetchChunk
définit la taille de chaque morceau et ne fait rien d'autre.
Gérer les fichiers dans les volumes de catalogue Unity
Databricks SQL Driver vous permet d’écrire des fichiers locaux dans des volumesdu catalogue Unity, de télécharger des fichiers à partir de volumes et de supprimer des fichiers des volumes, comme illustré dans l’exemple suivant :
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
const token = process.env.DATABRICKS_TOKEN;
if (!token || !serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"personal access token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
.then(async client => {
const session = await client.openSession();
// Write a local file to a volume in the specified path.
// For writing local files to volumes, you must first specify the path to the
// local folder that contains the file to be written.
// Specify OVERWRITE to overwrite any existing file in that path.
await session.executeStatement(
"PUT 'my-data.csv' INTO '/Volumes/main/default/my-volume/my-data.csv' OVERWRITE", {
stagingAllowedLocalPath: ["/tmp/"]
}
);
// Download a file from a volume in the specified path.
// For downloading files in volumes, you must first specify the path to the
// local folder that will contain the downloaded file.
await session.executeStatement(
"GET '/Volumes/main/default/my-volume/my-data.csv' TO 'my-downloaded-data.csv'", {
stagingAllowedLocalPath: ["/Users/paul.cornell/samples/nodejs-sql-driver/"]
}
)
// Delete a file in a volume from the specified path.
// For deleting files from volumes, you must add stagingAllowedLocalPath,
// but its value will be ignored. As such, in this example, an empty string is
// specified.
await session.executeStatement(
"REMOVE '/Volumes/main/default/my-volume/my-data.csv'", {
stagingAllowedLocalPath: [""]
}
)
await session.close();
await client.close();
})
.catch((error) => {
console.error(error);
});
TypeScript
import { DBSQLClient } from '@databricks/sql';
const serverHostname: string | undefined = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath: string | undefined = process.env.DATABRICKS_HTTP_PATH;
const token: string | undefined = process.env.DATABRICKS_TOKEN;
if (!token || !serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname, HTTP Path, or " +
"personal access token. " +
"Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
"DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
client.connect(connectOptions)
.then(async client => {
const session = await client.openSession();
// Write a local file to a volume in the specified path.
// For writing local files to volumes, you must first specify the path to the
// local folder that contains the file to be written.
// Specify OVERWRITE to overwrite any existing file in that path.
await session.executeStatement(
"PUT 'my-data.csv' INTO '/Volumes/main/default/my-volume/my-data.csv' OVERWRITE", {
stagingAllowedLocalPath: ["/tmp/"]
}
);
// Download a file from a volume in the specified path.
// For downloading files in volumes, you must first specify the path to the
// local folder that will contain the downloaded file.
await session.executeStatement(
"GET '/Volumes/main/default/my-volume/my-data.csv' TO 'my-downloaded-data.csv'", {
stagingAllowedLocalPath: ["/Users/paul.cornell/samples/nodejs-sql-driver/"]
}
)
// Delete a file in a volume from the specified path.
// For deleting files from volumes, you must add stagingAllowedLocalPath,
// but its value will be ignored. As such, in this example, an empty string is
// specified.
await session.executeStatement(
"REMOVE '/Volumes/main/default/my-volume/my-data.csv'", {
stagingAllowedLocalPath: [""]
}
)
await session.close();
await client.close();
})
.catch((error: any) => {
console.error(error);
});
Configuration de la journalisation
L’enregistreur d’événements fournit des informations sur les problèmes de débogage avec le connecteur. Tous les objets DBSQLClient
sont instanciés avec un enregistreur d’événements qui s’imprime sur la console, mais en passant un enregistreur d’événements personnalisé, vous pouvez envoyer ces informations à un fichier. L’exemple suivant montre comment configurer un enregistreur d’événements et modifier son niveau.
JavaScript
const { DBSQLLogger, LogLevel } = require('@databricks/sql');
const logger = new DBSQLLogger({
filepath: 'log.txt',
level: LogLevel.info
});
// Set logger to different level.
logger.setLevel(LogLevel.debug);
TypeScript
import { DBSQLLogger, LogLevel } from '@databricks/sql';
const logger = new DBSQLLogger({
filepath: 'log.txt',
level: LogLevel.info,
});
// Set logger to different level.
logger.setLevel(LogLevel.debug);
Pour obtenir d’autres exemples, consultez le dossier Exemples dans le référentiel databricks/databricks-sql-nodejs sur GitHub.
Test
Pour tester votre code, vous pouvez utiliser des frameworks de test JavaScript tels que Jest. Pour tester votre code dans des conditions simulées sans appeler des points de terminaison d’API REST Azure Databricks ni modifier l’état de vos comptes ou espaces de travail Azure Databricks, vous pouvez utiliser les frameworks fictifs intégrés de Jest.
Par exemple, étant donné le fichier suivant nommé helpers.js
contenant une fonction getDBSQLClientWithPAT
qui utilise un jeton d’accès personnel Azure Databricks pour retourner une connexion à un espace de travail Azure Databricks, une fonction getAllColumnsFromTable
qui utilise la connexion pour obtenir le nombre spécifié de lignes de données dans la table (par exemple, la table trips
dans le schéma nyctaxi
du catalogue samples
) et une fonction printResults
pour imprimer le contenu des lignes de données :
// helpers.js
const { DBSQLClient } = require('@databricks/sql');
async function getDBSQLClientWithPAT(token, serverHostname, httpPath) {
const client = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath
};
try {
return await client.connect(connectOptions);
} catch (error) {
console.error(error);
throw error;
}
}
async function getAllColumnsFromTable(client, tableSpec, rowCount) {
let session;
let queryOperation;
try {
session = await client.openSession();
queryOperation = await session.executeStatement(
`SELECT * FROM ${tableSpec} LIMIT ${rowCount}`,
{
runAsync: true,
maxRows: 10000 // This option enables the direct results feature.
}
);
} catch (error) {
console.error(error);
throw error;
}
let result;
try {
result = await queryOperation.fetchAll();
} catch (error) {
console.error(error);
throw error;
} finally {
if (queryOperation) {
await queryOperation.close();
}
if (session) {
await session.close();
}
}
return result;
}
function printResult(result) {
console.table(result);
}
module.exports = {
getDBSQLClientWithPAT,
getAllColumnsFromTable,
printResult
};
Et étant donné le fichier suivant nommé main.js
qui appelle les fonctions getDBSQLClientWithPAT
, getAllColumnsFromTable
et printResults
:
// main.js
const { getDBSQLClientWithPAT, getAllColumnsFromTable, printResult } = require('./helpers');
const token = process.env.DATABRICKS_TOKEN;
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
const tableSpec = process.env.DATABRICKS_TABLE_SPEC;
if (!token || !serverHostname || !httpPath) {
throw new Error("Cannot find Server Hostname, HTTP Path, or personal access token. " +
"Check the environment variables DATABRICKS_TOKEN, " +
"DATABRICKS_SERVER_HOSTNAME, and DATABRICKS_HTTP_PATH.");
}
if (!tableSpec) {
throw new Error("Cannot find table spec in the format catalog.schema.table. " +
"Check the environment variable DATABRICKS_TABLE_SPEC."
)
}
getDBSQLClientWithPAT(token, serverHostname, httpPath)
.then(async client => {
const result = await getAllColumnsFromTable(client, tableSpec, 2);
printResult(result);
await client.close();
})
.catch((error) => {
console.error(error);
});
Le fichier suivant nommé helpers.test.js
teste si la fonction getAllColumnsFromTable
retourne la réponse attendue. Au lieu de créer une connexion réelle à l’espace de travail cible, ce test simule un objet DBSQLClient
. Le test simule également des données qui sont conformes au schéma et aux valeurs qui se trouvent dans les données réelles. Le test renvoie les données simulées sur la connexion simulée, puis vérifie si une des valeurs des lignes de données simulées correspond à la valeur attendue.
// helpers.test.js
const { getDBSQLClientWithPAT, getAllColumnsFromTable, printResult} = require('./helpers')
jest.mock('@databricks/sql', () => {
return {
DBSQLClient: jest.fn().mockImplementation(() => {
return {
connect: jest.fn().mockResolvedValue({ mock: 'DBSQLClient'})
};
}),
};
});
test('getDBSQLClientWithPAT returns mocked Promise<DBSQLClient> object', async() => {
const result = await getDBSQLClientWithPAT(
token = 'my-token',
serverHostname = 'mock-server-hostname',
httpPath = 'mock-http-path'
);
expect(result).toEqual({ mock: 'DBSQLClient' });
});
const data = [
{
tpep_pickup_datetime: new Date(2016, 1, 13, 15, 51, 12),
tpep_dropoff_datetime: new Date(2016, 1, 13, 16, 15, 3),
trip_distance: 4.94,
fare_amount: 19.0,
pickup_zip: 10282,
dropoff_zip: 10171
},
{
tpep_pickup_datetime: new Date(2016, 1, 3, 17, 43, 18),
tpep_dropoff_datetime: new Date(2016, 1, 3, 17, 45),
trip_distance: 0.28,
fare_amount: 3.5,
pickup_zip: 10110,
dropoff_zip: 10110
}
];
const mockDBSQLClientForSession = {
openSession: jest.fn().mockResolvedValue({
executeStatement: jest.fn().mockResolvedValue({
fetchAll: jest.fn().mockResolvedValue(data),
close: jest.fn().mockResolvedValue(null)
}),
close: jest.fn().mockResolvedValue(null)
})
};
test('getAllColumnsFromTable returns the correct fare_amount for the second mocked data row', async () => {
const result = await getAllColumnsFromTable(
client = mockDBSQLClientForSession,
tableSpec = 'mock-table-spec',
rowCount = 2);
expect(result[1].fare_amount).toEqual(3.5);
});
global.console.table = jest.fn();
test('printResult mock prints the correct fare_amount for the second mocked data row', () => {
printResult(data);
expect(console.table).toHaveBeenCalledWith(data);
expect(data[1].fare_amount).toBe(3.5);
});
Pour TypeScript, le code précédent est similaire. Pour les tests Jest avec TypeScript, utilisez ts-jest.
Ressources supplémentaires
- Le référentiel Pilote Databricks SQL pour Node.js sur GitHub
- Prise en main de Databricks SQL Driver pour Node.js
- Dépannage du pilote Databricks SQL pour Node.js
Informations de référence sur l'API
Classes
Classe DBSQLClient
Point d’entrée principal pour interagir avec une base de données.
Méthodes
Méthode connect
Ouvre une connexion à la base de données.
Paramètres |
---|
options Entrez : ConnectionOptions Ensemble d’options utilisées pour se connecter à la base de données. Les champs host , path et les autres champs obligatoires doivent être remplis. Voir Authentification.Exemple : const client: DBSQLClient = new DBSQLClient(); client.connect( { host: serverHostname, path: httpPath, // ... } ) |
Retourne : Promise<IDBSQLClient>
Méthode openSession
Ouvre une session entre DBSQLClient et la base de données.
Paramètres |
---|
requête Entrez : OpenSessionRequest Ensemble de paramètres facultatifs pour spécifier le schéma initial et le catalogue initial Exemple : const session = await client.openSession( {initialCatalog: 'catalog'} ); |
Retourne : Promise<IDBSQLSession>
Méthode getClient
Retourne l’objet TCLIService.Client interne. Doit être appelé après la connexion de DBSQLClient.
Aucun paramètre
Renvoie TCLIService.Client
Méthode close
Ferme la connexion à la base de données et libère toutes les ressources associées sur le serveur. Tous les appels supplémentaires à ce client lèveront une erreur
Aucun paramètre.
Aucune valeur renvoyée.
Classe DBSQLSession
Les DBSQLSessions sont principalement utilisées pour l’exécution d’instructions sur la base de données, ainsi que pour diverses opérations d’extraction de métadonnées.
Méthodes
Méthode executeStatement
Exécute une instruction avec les options fournies.
Paramètres |
---|
instruction Entrez : str L’instruction T-SQL à exécuter. |
options Entrez : ExecuteStatementOptions Ensemble de paramètres facultatifs pour déterminer le délai d’expiration de la requête, le nombre maximal de lignes pour les résultats directs et l’exécution asynchrone de la requête. Par défaut, maxRows est défini sur 10000. Si maxRows est défini sur null, l’opération s’exécute avec la fonctionnalité de résultats directs désactivée.Exemple : const session = await client.openSession( {initialCatalog: 'catalog'} ); queryOperation = await session.executeStatement( 'SELECT "Hello, World!"', { runAsync: true } ); |
Retourne : Promise<IOperation>
Méthode close
Ferme la session. Doit être effectué après l’utilisation de la session.
Aucun paramètre.
Aucune valeur renvoyée.
Méthode getId
Retourne le GUID de la session.
Aucun paramètre.
Retourne : str
Méthode getTypeInfo
Retourne des informations sur les types de données pris en charge.
Paramètres |
---|
requête Entrez : TypeInfoRequest Paramètres de la requête. |
Retourne : Promise<IOperation>
Méthode getCatalogs
Obtient la liste des catalogues.
Paramètres |
---|
requête Entrez : CatalogsRequest Paramètres de la requête. |
Retourne : Promise<IOperation>
Méthode getSchemas
Obtient la liste des schémas.
Paramètres |
---|
requête Entrez : SchemasRequest Paramètres de la requête. Les champs catalogName et schemaName peuvent être utilisés à des fins de filtrage. |
Retourne : Promise<IOperation>
Méthode getTables
Obtient une liste de tables.
Paramètres |
---|
requête Entrez : TablesRequest Paramètres de la requête. Les champs catalogName et schemaName ettableName peuvent être utilisés pour le filtrage. |
Retourne : Promise<IOperation>
Méthode getFunctions
Obtient une liste de tables.
Paramètres |
---|
requête Entrez : FunctionsRequest Paramètres de la requête. Le champ functionName est requis. |
Retourne : Promise<IOperation>
Méthode getPrimaryKeys
Obtient la liste des clés primaires.
Paramètres |
---|
requête Entrez : PrimaryKeysRequest Paramètres de la requête. Les champs schemaName et tableName sont obligatoires. |
Retourne : Promise<IOperation>
Méthode getCrossReference
Obtient des informations sur les clés étrangères entre deux tables.
Paramètres |
---|
requête Entrez : CrossReferenceRequest Paramètres de la requête. Le schéma, le parent et le nom du catalogue doivent être spécifiés pour les deux tables. |
Retourne : Promise<IOperation>
Classe DBSQLOperation
Les DBSQLOperations sont créées par des DBSQLSessions et peuvent être utilisées pour extraire les résultats des instructions et vérifier leur exécution. Les données sont extraites via les fonctions fetchChunk et fetchAll.
Méthodes
Méthode getId
Retourne le GUID de l’opération.
Aucun paramètre.
Retourne : str
Méthode fetchAll
Attend la fin de l’opération, puis extrait toutes les lignes de l’opération.
Paramètres : aucun
Retourne : Promise<Array<object>>
Méthode fetchChunk
Attend la fin de l’opération, puis extrait jusqu’à un nombre spécifié de lignes à partir d’une opération.
Paramètres |
---|
options Entrez : FetchOptions Options utilisées pour extraire. Actuellement, la seule option est maxRows, qui correspond au nombre maximal d’objets de données à retourner dans un tableau donné. |
Retourne : Promise<Array<object>>
Méthode close
Ferme l’opération et libère toutes les ressources associées. Doit être effectué quand vous avez fini d’utiliser l’opération.
Aucun paramètre.
Aucune valeur renvoyée.