Driver Databricks SQL pour Node.js
Le Databricks SQL Driver pour Node.js est une bibliothèque Node.js qui vous permet d'utiliser du code JavaScript pour exécuter des commandes SQL sur des ressources de compute Databricks.
Exigences
-
Une machine de développement exécutant Node.js, version 14 ou supé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 packages de nœuds (
npm). Les versions ultérieures de Node.js incluent déjànpm. Pour vérifier sinpmest installé, exécutez la commandenpm -v. Pour installernpm, si nécessaire, vous pouvez suivre les instructions telles que celles disponibles à l'adresse download et installez npm. -
Le package @databricks/sql de npm. Pour installer le
@databricks/sqlpackage dans votre projet Node.js en tant que dépendance, utiliseznpmpour exécuter la commande suivante à partir du même répertoire que votre projet :Bashnpm i @databricks/sql -
Si vous souhaitez installer et utiliser TypeScript dans votre projet Node.js en tant que
devDependencies, utiliseznpmpour exécuter les commandes suivantes depuis le même répertoire que votre projet :Bashnpm i -D typescript
npm i -D @types/node -
Un cluster ou un SQL Warehouse existant.
-
La valeur Hostname du serveur et Chemin HTTP pour le cluster ou le SQL Warehouse existant.
Authentification
Le Driver SQL Databricks pour Node.js prend en charge les types d'authentification Databricks suivants :
- Authentification Databricks par jeton d'accès personnel
- Authentification OAuth machine à machine (M2M)
- Authentification OAuth utilisateur-à-machine (U2M)
Par mesure de sécurité, il est recommandé de ne pas coder en dur les valeurs des variables de connexion dans votre code. Au lieu de cela, vous devez récupérer les valeurs de ces variables de connexion à partir d'un emplacement sécurisé. Par exemple, les extraits de code et les exemples de cet article utilisent des variables d'environnement.
Authentification par jeton d'accès personnel Databricks
Pour utiliser le Databricks SQL Driver pour Node.js avec authentification, vous devez d'abord créer un jeton d'accès personnel Databricks. Pour plus de détails sur cette étape, consultez Créer des jetons d'accès personnels pour les utilisateurs de workspace.
Pour authentifier le Driver 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_HOSTNAMEdéfini sur la valeur **Hostname du serveur** de votre cluster ou SQL Warehouse.DATABRICKS_HTTP_PATH, défini sur la valeur Chemin HTTP pour votre cluster ou SQL Warehouse.DATABRICKS_TOKEN, défini sur le jeton d'accès personnel Databricks.
Pour définir les variables d’environnement, consultez la documentation de votre système d’exploitation.
- JavaScript
- TypeScript
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);
// ...
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 OAuth d'utilisateur à machine (U2M)
Le Driver Databricks SQL pour Node.js versions 1.3.0 et ultérieures prend en charge l'authentification OAuth utilisateur-à-machine (U2M).
Pour authentifier le Driver Databricks SQL pour Node.js avec l'authentification OAuth U2M, utilisez l'extrait de code suivant. Cet extrait suppose que vous avez défini les variables d'environnement suivantes :
DATABRICKS_SERVER_HOSTNAMEdéfini sur la valeur **Hostname du serveur** de votre cluster ou SQL Warehouse.DATABRICKS_HTTP_PATH, défini sur la valeur Chemin HTTP pour votre cluster ou SQL Warehouse.
Pour définir les variables d’environnement, consultez la documentation de votre système d’exploitation.
- JavaScript
- TypeScript
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',
host: serverHostname,
path: httpPath,
};
client.connect(connectOptions);
// ...
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',
host: serverHostname,
path: httpPath,
};
client.connect(connectOptions);
// ...
Authentification OAuth machine à machine (M2M)
Le Driver Databricks SQL pour Node.js versions 1.5.0 et ultérieures prend en charge l'authentification OAuth machine-to-machine (M2M).
Pour utiliser le Databricks SQL Driver pour Node.js avec l'authentification OAuth M2M, vous devez effectuer les opérations suivantes :
-
Créez un Service Principal Databricks dans votre Workspace Databricks, et créez un secret OAuth pour ce Service Principal.
Pour créer le service principal et son secret OAuth, consultez Autoriser l'accès du service principal à Databricks avec OAuth. Notez la valeur du **UUID** ou de l'**ID d'application** du service principal, ainsi que la valeur du **Secret** du secret OAuth du service principal.
-
Donnez au Service Principal l'accès à votre cluster ou votre warehouse. Consultez les autorisations Compute ou gérez un SQL Warehouse.
Pour authentifier le Driver 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_HOSTNAMEdéfini sur la valeur **Hostname du serveur** de votre cluster ou SQL Warehouse.DATABRICKS_HTTP_PATH, défini sur la valeur Chemin HTTP pour votre cluster ou SQL Warehouse.DATABRICKS_CLIENT_ID, défini sur la valeur **UUID** ou **ID d'Application** du Service Principal.DATABRICKS_CLIENT_SECRET, défini sur la valeur **Secret** du secret OAuth du Service Principal.
Pour définir les variables d’environnement, consultez la documentation de votre système d’exploitation.
- JavaScript
- TypeScript
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',
host: serverHostname,
path: httpPath,
oauthClientId: clientId,
oauthClientSecret: clientSecret,
};
client.connect(connectOptions);
// ...
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',
host: serverHostname,
path: httpPath,
oauthClientId: clientId,
oauthClientSecret: clientSecret,
};
client.connect(connectOptions);
// ...
Définir l'agent utilisateur
L'exemple de code suivant montre comment définir l'application User-Agent product_name pour le suivi de l'utilisation.
- JavaScript
const { DBSQLClient } = require('@databricks/sql');
const client = new DBSQLClient();
client.connect({
host: process.env.DATABRICKS_SERVER_HOSTNAME,
path: process.env.DATABRICKS_HTTP_PATH,
token: process.env.DATABRICKS_TOKEN,
userAgentEntry: 'product_name',
});
Query des données
L'exemple de code suivant montre comment appeler le Driver Databricks SQL pour Node.js pour exécuter une query SQL de base sur une ressource de compute Databricks. Cette commande renvoie les deux premières lignes de la table trips dans le schéma nyctaxi du catalogue samples.
L’exemple de code suivant montre comment utiliser un jeton d’accès personnel Databricks pour l’authentification. Pour utiliser d’autres types d’authentification Databricks disponibles, consultez la section Authentification.
Cet exemple de code récupère les valeurs de variable de connexion token, server_hostname et http_path à partir d'un ensemble de variables d'environnement Databricks. Ces variables d'environnement ont les noms de variables d'environnement suivants :
DATABRICKS_TOKEN, qui représente votre jeton d'accès personnel Databricks à partir des exigences.DATABRICKS_SERVER_HOSTNAME, qui représente la valeur **Hostname du serveur** des exigences.DATABRICKS_HTTP_PATH, qui représente la valeur Chemin HTTP des exigences.
Vous pouvez utiliser d'autres approches pour récupérer ces valeurs de variables de connexion. L'utilisation de variables d'environnement n'est qu'une approche parmi tant d'autres.
L'exemple de code suivant montre comment appeler le Databricks SQL Connector for Node.js pour exécuter une commande SQL de base sur un cluster ou un SQL Warehouse. Cette commande renvoie les deux premières lignes de la table trips.
- JavaScript
- TypeScript
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 ?', {
runAsync: true,
maxRows: 10000, // This option enables the direct results feature.
ordinalParameters: [2],
});
const result = await queryOperation.fetchAll();
await queryOperation.close();
console.table(result);
await session.close();
await client.close();
})
.catch((error) => {
console.error(error);
});
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 ?', {
runAsync: true,
maxRows: 10000, // This option enables the direct results feature.
ordinalParameters: [2],
});
const result = await queryOperation.fetchAll();
await queryOperation.close();
console.table(result);
await session.close();
client.close();
})
.catch((error) => {
console.error(error);
});
Exemple de tags de query
Aperçu
Cette fonctionnalité est en aperçu public.
Les tags de query sont des paires clé-valeur qui peuvent être attachées aux query SQL à des fins de suivi et d'analyse. Une fois définis, ils apparaissent dans la table system.query.history, ce qui vous permet d'analyser les modèles de query et l'utilisation.
Définissez les étiquettes de requête comme des paires clé-valeur séparées par des virgules où chaque clé et valeur est séparée par un deux-points, par exemple : key1:value1,key2:value2.
L'exemple suivant montre comment utiliser les balises de query avec la configuration de session :
- JavaScript
- TypeScript
const { DBSQLClient } = require('@databricks/sql');
const client = new DBSQLClient();
// Open session with query tags configuration
const session = await client.openSession({
configuration: {
query_tags: 'team:engineering,test:query-tags,driver:node',
},
});
const queryOperation = await session.executeStatement('SELECT 1');
const result = await queryOperation.fetchAll();
console.log(result);
await queryOperation.close();
await session.close();
import { DBSQLClient } from '@databricks/sql';
const client: DBSQLClient = new DBSQLClient();
// Open session with query tags configuration
const session = await client.openSession({
configuration: {
query_tags: 'team:engineering,test:query-tags,driver:node',
},
});
const queryOperation = await session.executeStatement('SELECT 1');
const result = await queryOperation.fetchAll();
console.log(result);
await queryOperation.close();
await session.close();
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 fait de définir
runAsyncàtruestart le mode asynchrone. Les méthodesIDBSQLSessionplacent les opérations dans la file d’attente et renvoient les résultats aussi rapidement que possible. L’état actuel de l’objetIOperationrenvoyé peut varier, et le client est responsable de vérifier son état avant d’utiliser leIOperationrenvoyé. See Opérations. DéfinirrunAsyncàfalsesignifie que les méthodesIDBSQLSessionattendent la fin des Opérations. Databricks recommande de toujours définirrunAsyncàtrue. - Définir
maxRowssur une valeur non nulle permet d'obtenir des résultats directs. Avec les résultats directs, le serveur tente d'attendre que les opérations se terminent, puis récupère une partie des données. Selon la quantité de travail que le serveur a pu effectuer dans le délai défini,IOperationobjets sont renvoyés dans un état intermédiaire au lieu d'un état en attente. Très souvent, toutes les métadonnées et les résultats de la query sont renvoyés dans une seule demande au serveur. Le serveur utilisemaxRowspour déterminer le nombre d'enregistrements qu'il peut renvoyer immédiatement. Cependant, le segment réel peut avoir une taille différente ; voirIDBSQLSession.fetchChunk. Les résultats directs sont activés par default. Databricks déconseille de désactiver les résultats directs.
Configuration de session
Vous pouvez transmettre les paramètres de configuration de session lors de l'ouverture d'une session à l'aide de l'objet configuration dans la méthode openSession. Ces paramètres affectent le comportement de toutes les opérations au sein de cette session.
Les paramètres de configuration de session courants incluent :
query_tags: associez des balises clé-valeur aux queries SQL pour le suivi et l'analytique. Pour plus d'informations, consultez l'exemple de balises de query.ansi_mode: Contrôle le mode de conformité ANSI SQL ('true'ou'false')timezone: Définit le fuseau horaire de la session (par exemple,'UTC','America/New_York')
Opérations
Comme décrit dans Sessions, les objets IOperation renvoyés par les méthodes de session IDBSQLSession dans la référence de l’API ne sont pas entièrement renseignés. L'opération de serveur associée peut toujours être en cours, par exemple en attente du start du warehouse Databricks SQL, de l'exécution de la query ou de la récupération des données. La classe IOperation masque ces détails aux utilisateurs. Par exemple, des méthodes telles que fetchAll, fetchChunk et getSchema attendent en interne que les opérations se terminent, puis renvoient les résultats. Vous pouvez utiliser la méthode IOperation.finished() pour attendre explicitement que les opérations se terminent. Ces méthodes acceptent une fonction de rappel qui est appelée périodiquement jusqu'à ce que les opérations soient terminées. Le réglage de l’option progress sur true tente de demander des données de progression supplémentaires au serveur et de les transmettre à ce callback.
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 a peut-être déjà été effectuée et la méthode cancel n'affecte que 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 entraîner des erreurs de mémoire lorsqu'il est utilisé sur de grands datasets. fetchAll options sont généralement transmises à fetchChunk.
Récupérer des morceaux de données
La récupération des 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 de l'API traite les données en petites portions afin de 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 une fonction de rappel pendant le cycle d'attente, et récupère ensuite le prochain bloc de données.
Vous pouvez utiliser l'option maxRows pour spécifier la taille de bloc souhaitée. Cependant, le segment renvoyé peut avoir une taille différente, plus petite ou même parfois plus grande. fetchChunk n’essaie pas de précharger les données en interne afin de les découper en parties demandées. Il envoie l'option maxRows au serveur, et renvoie ce que le serveur retourne. Ne confondez pas cette option maxRows avec celle de IDBSQLSession. La valeur maxRows transmise à fetchChunk définit la taille de chaque segment et ne fait rien d'autre.
Gérer les fichiers dans les volumes Unity Catalog
Le Driver Databricks SQL vous permet d'écrire des fichiers locaux dans les volumes Unity Catalog, de download des fichiers depuis des volumes et de supprimer des fichiers des volumes, comme le montre l'exemple suivant :
- JavaScript
- TypeScript
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);
});
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);
});
Configurer la journalisation
L'enregistreur fournit des informations pour le debugging des problèmes liés au connecteur. Tous les objets DBSQLClient sont instanciés avec un enregistreur qui écrit dans la console, mais en transmettant un enregistreur personnalisé, vous pouvez envoyer cette information à un fichier. L'exemple suivant montre comment configurer un enregistreur et modifier son niveau.
- JavaScript
- TypeScript
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);
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 d'autres exemples, consultez le dossier exemples dans le repository databricks/databricks-sql-nodejs sur GitHub.
Utilisez l'API d'exécution des instructions
Le Driver Databricks SQL pour Node.js peut se connecter à l'aide de l'API Statement Execution, un chemin d'exécution basé sur REST, au lieu du protocole Thrift par default. Vous devez utiliser ce chemin pour vous connecter au compute Lakehouse Real-Time.
Le connecteur fournit des binaires natifs préintégrés pour les plateformes courantes. npm install sélectionne automatiquement la bonne pour votre plateforme :
npm install @databricks/sql
Lorsque vous vous connectez, transmettez useKernel: true:
const { DBSQLClient } = require('@databricks/sql');
const client = new DBSQLClient();
await client.connect({ host, path, token, useKernel: true });
const session = await client.openSession();
const operation = await session.executeStatement('SELECT 1');
console.log(await operation.fetchAll());
Ce chemin d’exécution n’est utilisé que si vous définissez useKernel: true. Autrement, le driver se comporte comme dans les versions précédentes. Certaines opérations ne sont pas encore prises en charge sur ce chemin et génèrent une erreur « non prise en charge ».
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 les Endpoint d'API REST Databricks ni modifier l'état de vos comptes ou Workspace Databricks, vous pouvez utiliser les frameworks de simulation 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 Databricks pour renvoyer une connexion à un Workspace Databricks, une fonction getAllColumnsFromTable qui utilise la connexion pour obtenir le nombre spécifié de lignes de données à partir de la table spécifiée (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();
// Note: Table names cannot be parameterized; validate tableSpec against allowed values
queryOperation = await session.executeStatement(`SELECT * FROM ${tableSpec} LIMIT ?`, {
runAsync: true,
maxRows: 10000, // This option enables the direct results feature.
ordinalParameters: [rowCount],
});
} 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,
};
É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 renvoie la réponse attendue. Plutôt que de créer une connexion réelle au Workspace cible, ce test simule un objet DBSQLClient. Le test simule également des données qui sont conformes au schéma et aux valeurs présentes dans les données réelles. Le test renvoie les données mockées via la connexion mockée, puis vérifie si l'une des valeurs des lignes de données mockées correspond à la valeur attendue.
// helpers.test.js
const { getDBSQLClientWithPAT, getAllColumnsFromTable, printResult } = require('./helpers');
jest.mock('@databricks/sql', () => {
return {
DBSQLClient: jest.fn(() => {
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 ressemble à ceci. Pour les tests Jest avec TypeScript, utilisez ts-jest.
Ressources supplémentaires
- Le repository Databricks SQL Driver pour Node.js sur GitHub
- Démarrer avec le Driver Databricks SQL pour Node.js
- Dépannage du Driver Databricks SQL pour Node.js
Référence de l'API
Classes
ClasseDBSQLClient
Point d'entrée principal pour interagir avec une base de données.
Méthodes
méthodeconnect
Ouvre une connexion à la base de données.
Paramètres |
|---|
Options Type : L'ensemble d'options utilisées pour se connecter à la base de données. Les champs Le champ |
Renvoie :
Promise<IDBSQLClient>
méthodeopenSession
Ouvre une session entre DBSQLClient et la base de données.
Paramètres |
|---|
demande Type : Un ensemble de parameters facultatifs pour spécifier le schéma initial et le catalogue initial Exemple : JavaScript |
Renvoie :
Promise<IDBSQLSession>
méthodegetClient
Renvoie un objet client thrift TCLIService.Client interne. Doit être appelé après la connexion de DBSQLClient.
Aucun paramètre
Renvoie TCLIService.Client
méthodeclose
Ferme la connexion à la base de données et libère toutes les ressources associées sur le serveur. Tout appel supplémentaire à ce client générera une erreur.
Aucun paramètre.
Aucune valeur de retour.
ClasseDBSQLSession
Les DBSQLSessions sont principalement utilisées pour l'exécution d'instructions sur la base de données ainsi que pour diverses Opérations de récupération de métadonnées.
Méthodes
méthodeexecuteStatement
Exécute une instruction avec les options fournies.
Paramètres |
|---|
déclaration Type : L'instruction à exécuter. Options Type : Un ensemble de parameters facultatifs pour déterminer le délai d'expiration de la query, le nombre maximal de lignes pour les résultats directs et si la query doit être exécutée de manière asynchrone. Par default, Exemple : JavaScript |
Renvoie :
Promise<IOperation>
méthodeclose
Ferme la session. Doit être fait après avoir utilisé la session.
Aucun paramètre.
Aucune valeur de retour.
méthodegetId
Renvoie le GUID de la session.
Aucun paramètre.
Renvoie :
str
méthodegetTypeInfo
Retourne des informations sur les types de données pris en charge.
Paramètres |
|---|
demande Type : Paramètres de la requête. |
Renvoie :
Promise<IOperation>
méthodegetCatalogs
Obtient la liste des catalogues.
Paramètres |
|---|
demande Type : Paramètres de la requête. |
Renvoie :
Promise<IOperation>
méthodegetSchemas
Obtient la liste des schémas.
Paramètres |
|---|
demande Type : Paramètres de la requête. Les champs |
Renvoie :
Promise<IOperation>
méthodegetTables
Obtient la liste des tables.
Paramètres |
|---|
demande Type : Paramètres de la requête. Les champs |
Renvoie :
Promise<IOperation>
méthodegetFunctions
Obtient la liste des tables.
Paramètres |
|---|
demande Type : Paramètres de la requête. Le champ |
Renvoie :
Promise<IOperation>
méthodegetPrimaryKeys
Obtient la liste des clés primaires.
Paramètres |
|---|
demande Type : Paramètres de la requête. Les champs |
Renvoie :
Promise<IOperation>
méthodegetCrossReference
Obtient des information sur les clés étrangères entre deux tables.
Paramètres |
|---|
demande Type : Paramètres de la requête. Le nom du schéma, du parent et du catalogue doivent être spécifiés pour les deux tables. |
Renvoie :
Promise<IOperation>
ClasseDBSQLOperation
Les DBSQLOperations sont créées par les DBSQLSessions et peuvent être utilisées pour récupérer les résultats des instructions et vérifier leur exécution. Les données sont récupérées par les fonctions fetchChunk et fetchAll.
Méthodes
méthodegetId
Renvoie le GUID de l'opération.
Aucun paramètre.
Renvoie :
str
méthodefetchAll
Attend la fin de l'opération, puis récupère toutes les lignes de l'opération.
Paramètres : Aucun
Renvoie :
Promise<Array<object>>
méthodefetchChunk
Attend la fin de l'opération, puis récupère jusqu'à un nombre spécifié de lignes d'une opération.
Paramètres |
|---|
Options Type : Options utilisées pour la récupération. Actuellement, la seule option est maxRows, qui correspond au nombre maximum d'objets de données à renvoyer dans un tableau donné. |
Renvoie :
Promise<Array<object>>
méthodeclose
Ferme l'opération et libère toutes les ressources associées. Cela doit être effectué après ne plus utiliser l'opération.
Aucun paramètre.
Aucune valeur de retour.