Freigeben über


Databricks SQL-Treiber für Node.js

Der Databricks SQL-Treiber für Node.js ist eine Node.js-Bibliothek, mit der Sie JavaScript-Code verwenden können, um SQL-Befehle auf Azure Databricks-Computeressourcen auszuführen.

Anforderungen

  • Ein Entwicklungscomputer mit Node.js, Version 14 oder höher Führen Sie den Befehl node -v aus, um die installierte Version von Node.js auszugeben. Für die Installation und Verwendung verschiedener Versionen von Node.js können Sie Tools wie Node Version Manager (nvm) verwenden.

  • Node-Paket-Manager (npm). Spätere Versionen von Node.js enthalten bereits npm. Führen Sie den Befehl npm -v aus, um zu überprüfen, ob npm installiert ist. Zur Installation von npm können Sie bei Bedarf Anweisungen wie die unter Herunterladen und Installieren von npm befolgen.

  • Das @databricks/sql-Paket von npm. Wenn Sie das @databricks/sql-Paket in Ihrem Node.js-Projekt als Abhängigkeit installieren möchten, verwenden Sie npm, um den folgenden Befehl im gleichen Verzeichnis auszuführen, in dem sich auch Ihr Projekt befindet:

    npm i @databricks/sql
    
  • Wenn Sie TypeScript in Ihrem Node.js-Projekt als devDependencies installieren und verwenden möchten, verwenden Sie npm, um die folgenden Befehle im gleichen Verzeichnis auszuführen, in dem sich auch Ihr Projekt befindet:

    npm i -D typescript
    npm i -D @types/node
    
  • Ein vorhandener Cluster oder vorhandenes SQL-Warehouse.

  • Der Wert des Serverhostnamens und des HTTP-Pfads für das vorhandene Cluster oder SQL-Warehouse.

Authentifizierung

Der Databricks SQL-Treiber für Node.js unterstützt die folgenden Azure Databricks-Authentifizierungstypen:

Der Databricks SQL-Treiber für Node.js unterstützt die folgenden Azure Databricks-Authentifizierungstypen:

Hinweis

Als bewährte Sicherheitspraxis sollten Sie die Werte von Verbindungsvariablen nicht fest in Ihrem Code codieren. Stattdessen sollten Sie die Werte dieser Verbindungsvariablen von einem sicheren Ort abrufen. Die Codeschnipsel und Beispiele in diesem Artikel verwenden zum Beispiel Umgebungsvariablen.

Databricks persönliche Zugriffstoken-Authentifizierung

Um den Databricks SQL-Treiber für Node.js mit der persönlichen Zugriffstoken-Authentifizierung von Azure Databricks zu verwenden, müssen Sie zunächst ein persönliches Zugriffstoken von Azure Databricks erstellen, wie folgt:

  1. Wählen Sie in Ihrem Azure Databricks-Arbeitsbereich in der oberen Leiste Ihren Azure Databricks-Benutzernamen und dann im Dropdownmenü die Option Einstellungen aus.
  2. Klicken Sie auf Entwickler.
  3. Klicken Sie neben Zugriffstoken auf Verwalten.
  4. Klicken Sie auf Neues Token generieren.
  5. (Optional) Geben Sie einen Kommentar ein, durch den Sie dieses Token in Zukunft identifizieren können, und ändern Sie die standardmäßige Lebensdauer des Tokens von 90 Tagen. Wenn Sie ein Token ohne Gültigkeitsdauer erstellen möchten (nicht empfohlen), lassen Sie das Feld Lebensdauer (Tage) leer.
  6. Klicken Sie auf Generate (Generieren) .
  7. Kopieren Sie das angezeigte Token an einen sicheren Speicherort, und klicken Sie auf Fertig.

Hinweis

Achten Sie darauf, den kopierten Token an einem sicheren Ort zu speichern. Geben Sie das kopierte Token nicht an andere Personen weiter. Wenn Sie das kopierte Token verlieren, können Sie das gleiche Token nicht erneut generieren. Stattdessen müssen Sie erneut das Verfahren zum Erstellen eines neuen Tokens durchlaufen. Wenn Sie das kopierte Token verlieren oder glauben, dass das Token kompromittiert wurde, empfiehlt Databricks dringend, dass Sie das Token sofort aus Ihrem Arbeitsbereich löschen. Klicken Sie hierzu auf der Seite Zugriffstoken auf das Papierkorbsymbol (Widerrufen) neben dem Token.

Wenn Sie in Ihrem Arbeitsbereich keine Token erstellen oder verwenden können, liegt dies möglicherweise daran, dass Ihr Arbeitsbereichsadministrator Token deaktiviert hat oder Ihnen keine Berechtigung zum Erstellen oder Verwenden von Token erteilt hat. Wenden Sie sich an Ihren Arbeitsbereichsadministrator oder lesen Sie die folgenden Themen:

Verwenden Sie zum Authentifizieren des Databricks SQL-Treibers für Node.js das folgende Codeschnipsel. Dieses Codeschnipsel setzt voraus, dass Sie die folgenden Umgebungsvariablen gesetzt haben:

  • DATABRICKS_SERVER_HOSTNAMEauf den Wert für den Server-Hostnamen Ihres Clusters oder SQL-Warehouses gesetzt.
  • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • DATABRICKS_TOKEN ist auf das persönliche Azure Databricks-Zugriffstoken festgelegt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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)
  // ...

OAuth U2M-Authentifizierung (User-to-Machine)

Databricks SQL-Treiber für Node.js Version 1.8.0 und höher unterstützen OAuth-User-to-Machine-Authentifizierung (U2M).

Um den Databricks SQL-Treiber für Node.js mit der OAuth U2M-Authentifizierung zu authentifizieren, verwenden Sie den folgenden Codeausschnitt. Bei diesem Codeschnipsel wird davon ausgegangen, dass Sie die folgenden Umgebungsvariablen festgelegt haben:

  • DATABRICKS_SERVER_HOSTNAMEauf den Wert für den Server-Hostnamen Ihres Clusters oder SQL-Warehouses gesetzt.
  • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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)
  // ...

OAuth-Computer-zu-Computer-Authentifizierung (M2M)

Databricks SQL-Treiber für Node.js Version 1.8.0 und höher unterstützen OAuth Machine-to-Machine-Authentifizierung (M2M).

Um den Databricks-SQL-Treiber für Node.js mit der OAuth-M2M-Authentifizierung zu verwenden, müssen Sie die folgenden Schritte ausführen:

  1. Erstellen Sie einen Azure Databricks-Dienstprinzipal in Ihrem Azure Databricks-Arbeitsbereich, und erstellen Sie ein OAuth-Geheimnis für diesen Dienstprinzipal.

    Informationen zum Erstellen des Dienstprinzipals und des geheimen OAuth-Schlüssels finden Sie unter Authentifizierung des Zugriffs bei Azure Databricks mit einem Dienstprinzipal unter Verwendung von OAuth (OAuth M2M). Notieren Sie sich den UUID- oder Anwendungs-ID-Wert des Dienstprinzipals und den Geheimniswert für das OAuth-Geheimnis des Dienstprinzipals.

  2. Gewähren Sie dem Dienstprinzipal Zugriff auf Ihren Cluster oder Ihr Warehouse. Weitere Informationen finden Sie unter Compute-Berechtigungen und Verwaltung eines SQL-Warehouse.

Verwenden Sie zum Authentifizieren des Databricks SQL-Treibers für Node.js das folgende Codeschnipsel. Dieses Codeschnipsel setzt voraus, dass Sie die folgenden Umgebungsvariablen gesetzt haben:

  • DATABRICKS_SERVER_HOSTNAMEauf den Wert für den Server-Hostnamen Ihres Clusters oder SQL-Warehouses gesetzt.
  • DATABRICKS_HTTP_PATH ist auf den Wert von HTTP-Pfad für Ihren Cluster oder Ihr SQL-Warehouse festgelegt.
  • Legen Sie DATABRICKS_CLIENT_ID auf den UUID- oder Anwendungs-ID-Wert des Dienstprinzipals fest.
  • DATABRICKS_CLIENT_SECRET ist auf den Wert Geheimnis für das OAuth-Geheimnis des Dienstprinzipals festgelegt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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)
  // ...

Microsoft Entra ID-Tokenauthentifizierung

Um den Databricks SQL-Treiber für Node.js mit der Microsoft Entra ID-Tokenauthentifizierung zu verwenden, müssen Sie den Databricks SQL-Treiber für Node.js mit dem Microsoft Entra ID-Token bereitstellen. Gehen Sie wie folgt vor, um ein Microsoft Entra ID-Zugriffstoken zu erstellen:

Microsoft Entra ID-Token haben eine Standardlebensdauer von ca. 1 Stunde. Wiederholen Sie diesen Vorgang, um ein neues Microsoft Entra ID-Token zu erstellen.

Verwenden Sie zum Authentifizieren des Databricks SQL-Treibers für Node.js das folgende Codeschnipsel. Dieses Codeschnipsel setzt voraus, dass Sie die folgenden Umgebungsvariablen gesetzt haben:

  • DATABRICKS_SERVER_HOSTNAMEauf den Wert für den Server-Hostnamen Ihres Clusters oder SQL-Warehouses gesetzt.
  • DATABRICKS_HTTP_PATH, auf den Wert des HTTP-Pfads für Ihren Cluster oder Ihr SQL-Warehouse gesetzt.
  • DATABRICKS_TOKEN, auf das Microsoft Entra ID-Token gesetzt.

Informationen zum Festlegen von Umgebungsvariablen finden Sie in der Dokumentation des Betriebssystems.

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)
  // ...

Daten abfragen

Im folgenden Codebeispiel wird veranschaulicht, wie Sie den Databricks SQL-Treiber für Node.js aufrufen können, um eine einfache SQL-Abfrage in einer Azure Databricks-Computeressource auszuführen. Dieser Befehl gibt die ersten beiden Zeilen aus der trips Tabelle im Schema des samples Katalogs nyctaxi zurück.

Hinweis

Im folgenden Codebeispiel wird die Verwendung eines persönlichen Azure Databricks-Zugriffstokens für die Authentifizierung veranschaulicht. Informationen zum Verwenden anderer verfügbarer Azure Databricks-Authentifizierungstypen finden Sie unter Authentifizierung.

Dieses Codebeispiel ruft die Verbindungsvariablenwerte für token, server_hostname und http_path aus einer Reihe von Azure Databricks-Umgebungsvariablen ab. Diese Umgebungsvariablen haben die folgenden Namen:

  • DATABRICKS_TOKEN, das das persönliche Zugriffstoken für Azure Databricks aus den Anforderungen darstellt.
  • DATABRICKS_SERVER_HOSTNAME, das den Serverhostname-Wert aus den Anforderungen darstellt.
  • DATABRICKS_HTTP_PATH, das den HTTP-Pfad-Wert aus den Anforderungen darstellt.

Sie können auch andere Methoden verwenden, um diese Verbindungsvariablenwerte abzurufen. Die Verwendung von Umgebungsvariablen ist nur ein Ansatz unter vielen.

Das folgende Codebeispiel veranschaulicht, wie der Databricks SQL-Connector für Node.js aufgerufen wird, um einen einfachen SQL-Befehl in einem Cluster oder SQL-Warehouse auszuführen. Dieser Befehl gibt die ersten beiden Zeilen der trips-Tabelle zurück.

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);
});

Ausgabe:

┌─────────┬─────┬────────┬───────────┬───────┬─────────┬────────┬───────┬───────┬────────┬────────┬────────┐
│ (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' │
└─────────┴─────┴────────┴───────────┴───────┴─────────┴────────┴───────┴───────┴────────┴────────┴────────┘

Sitzungen

Alle IDBSQLSession-Methoden, die in der API-Referenz Objekte vom Typ IOperation zurückgeben, verfügen über die folgenden allgemeinen Parameter, die sich auf ihr Verhalten auswirken:

  • Durch Festlegen von runAsync auf true wird der asynchrone Modus gestartet. IDBSQLSession-Methoden reihen Vorgänge in die Warteschlange ein und werden schnellstmöglich abgeschlossen. Der aktuelle Zustand des zurückgegebenen IOperation-Objekts kann variieren, und der Client ist dafür verantwortlich, vor der Verwendung des zurückgegebenen IOperation-Objekts den Status zu überprüfen. Weitere Informationen finden Sie unter Vorgänge. Wenn runAsync auf false festgelegt wird, warten IDBSQLSession-Methoden auf den Abschluss von Vorgängen. Databricks empfiehlt, runAsync immer auf true festzulegen.
  • Das Festlegen von maxRows auf einen Wert ungleich NULL ermöglicht direkte Ergebnisse. Bei direkten Ergebnissen versucht der Server, auf den Abschluss von Vorgängen zu warten, und ruft dann einen Teil der Daten ab. Abhängig davon, wie viel der Server innerhalb der definierten Zeit erledigen konnte, werden IOperation-Objekte ggf. in einem Zwischenzustand und nicht in einem ausstehenden Zustand zurückgegeben. Sehr häufig werden alle Metadaten und Abfrageergebnisse innerhalb einer einzelnen Anforderung an den Server zurückgegeben. Der Server verwendet maxRows, um zu bestimmen, wie viele Datensätze sofort zurückgegeben werden können. Der tatsächliche Block kann jedoch eine andere Größe aufweisen (siehe IDBSQLSession.fetchChunk). Direkte Ergebnisse sind standardmäßig aktiviert. Databricks rät davon ab, direkte Ergebnisse zu deaktivieren.

Operationen (Operations)

Wie unter Sitzungen beschrieben, werden IOperation-Objekte, die von IDBSQLSession-Sitzungsmethoden in der API-Referenz zurückgegeben werden, nicht vollständig aufgefüllt. Der zugehörige Servervorgang wird möglicherweise noch ausgeführt. Beispiele wären etwa das Warten auf den Start des Databricks SQL-Warehouse, das Ausführen der Abfrage oder das Abrufen der Daten. Die IOperation-Klasse blendet diese Details für Benutzer*innen aus. Methoden wie fetchAll, fetchChunk und getSchema warten beispielsweise intern, bis Vorgänge abgeschlossen sind, und geben dann Ergebnisse zurück. Sie können die IOperation.finished()-Methode verwenden, um explizit auf den Abschluss von Vorgängen zu warten. Diese Methoden verwenden einen Rückruf, der regelmäßig aufgerufen wird, während auf den Abschluss von Vorgängen gewartet wird. Wenn die Option progress auf true festgelegt wird, wird versucht, zusätzliche Fortschrittsdaten vom Server anzufordern und an diesen Rückruf zu übergeben.

Die Methoden close und cancel können jederzeit aufgerufen werden. Durch den Aufruf wird das IOperation-Objekt sofort ungültig gemacht. Alle ausstehenden Aufrufe wie fetchAll, fetchChunk und getSchema werden sofort abgebrochen, und ein Fehler wird zurückgegeben. In einigen Fällen ist der Servervorgang möglicherweise bereits abgeschlossen, und die cancel-Methode wirkt sich nur auf den Client aus.

Die fetchAll-Methode ruft intern fetchChunk auf und sammelt alle Daten in einem Array. Das ist zwar praktisch, kann bei der Verwendung in großen Datasets aber zu Fehlern aufgrund von unzureichendem Arbeitsspeicher führen. Optionen vom Typ fetchAll werden in der Regel an fetchChunkübergeben.

Abrufen von Datenblöcken

Beim Abrufen von Datenblöcken wird das folgende Codemuster verwendet:

do {
  const chunk = await operation.fetchChunk();
  // Process the data chunk.
} while (await operation.hasMoreRows());

Die fetchChunk-Methode in der API-Referenz verarbeitet Daten in kleinen Teilen, um die Arbeitsspeicherauslastung zu reduzieren. fetchChunk wartet zunächst, bis Vorgänge abgeschlossen sind (sofern sie noch nicht abgeschlossen wurden), ruft dann während des Wartezyklus einen Rückruf auf, und ruft anschließend den nächsten Datenblock ab.

Sie können die Option maxRows verwenden, um die gewünschte Blockgröße anzugeben. Der zurückgegebene Block kann jedoch eine andere Größe haben und kleiner oder manchmal auch größer sein. fetchChunk versucht nicht, Daten intern vorab abzurufen, um sie in die angeforderten Teile zu partitionieren. Die Option maxRows wird an den Server gesendet, und die Rückgabe des Servers wird zurückgegeben. Diese maxRows-Option darf nicht mit der Option in IDBSQLSession verwechselt werden. Die Übergabe von maxRows an fetchChunk definiert ausschließlich die Größe der einzelnen Blöcke.

Verwalten von Dateien in Unity Catalog-Volumes

Mit dem Databricks SQL-Treiber können Sie lokale Dateien in Unity Catalog-Volumes schreiben, Dateien aus Volumes herunterladen und Dateien aus Volumes löschen, wie im folgenden Beispiel gezeigt:

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);
  });

Konfigurieren der Protokollierung

Die Protokollierung bietet Informationen zum Debuggen von Problemen mit dem Connector. Alle DBSQLClient-Objekte werden mit einer Protokollierung instanziiert, die Ergebnisse an die Konsole ausgibt, aber durch Übergeben einer benutzerdefinierten Protokollierung können Sie diese Informationen an eine Datei senden. Das folgende Beispiel zeigt, wie Sie eine Protokollierung konfigurieren und den Protokollierungsgrad ändern.

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);

Weitere Beispiele finden Sie im Beispielordner im Repository „databricks/databricks-sql-nodejs“ auf GitHub.

Testen

Um Ihren Code zu testen, können Sie JavaScript-Testframeworks wie Jest verwenden. Um Ihren Code unter simulierten Bedingungen zu testen, ohne Azure Databricks-REST-API-Endpunkte aufzurufen oder den Status Ihrer Azure Databricks-Konten oder -Arbeitsbereiche zu ändern, können Sie die beinhalteten Modellbibliotheken von Jest verwenden.

Ein Beispiel: Angenommen, die folgende Datei namens helpers.js enthält eine getDBSQLClientWithPAT-Funktion, die ein persönliches Azure Databricks-Zugriffstoken verwendet, um eine Verbindung mit einem Azure Databricks-Arbeitsbereich zurückzugeben, eine getAllColumnsFromTable-Funktion, welche die Verbindung verwendet, um die angegebene Anzahl von Datenzeilen aus der angegebenen Tabelle (z. B. der Tabelle trips im Schema nyctaxi des Katalogs samples) abzurufen und eine printResults-Funktion, um den Inhalt der Datenzeilen zu drucken:

// 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
};

Nehmen wir außerdem an, die folgende Datei mit dem Namen main.js ruft die Funktionen getDBSQLClientWithPAT, getAllColumnsFromTable und printResults auf:

// 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);
  });

Die folgende Datei mit dem Namen helpers.test.js testet, ob die getAllColumnsFromTable Funktion die erwartete Antwort zurückgibt. Anstatt eine echte Verbindung mit dem Zielarbeitsbereich zu erstellen, simuliert dieser Test ein DBSQLClient-Objekt. Zudem simuliert der Test einige Daten, die dem Schema und den Werten aus den realen Daten entsprechen. Der Test gibt die simulierten Daten über die simulierte Verbindung zurück und überprüft dann, ob einer der simulierten Datenzeilenwerte dem erwarteten Wert entspricht.

// 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);
});

Für TypeScript sieht der voranstehende Code ähnlich aus. Verwenden Sie für Jest-Tests mit TypeScript ts-jest.

Zusätzliche Ressourcen

API-Referenz

Klassen

DBSQLClient-Klasse

Haupteinstiegspunkt für die Interaktion mit einer Datenbank.

Methoden
connect-Methode

Öffnet eine Verbindung mit der Datenbank.

Parameter
options

Geben Sie Folgendes ein: ConnectionOptions

Der Satz Optionen, die zum Herstellen einer Verbindung mit der Datenbank verwendet werden.

Die Felder host, path und andere Pflichtfelder müssen aufgefüllt werden. Siehe Authentifizierung.

Beispiel:


const client: DBSQLClient = new DBSQLClient();

client.connect(
{
host: serverHostname,
path: httpPath,
// ...
}
)

Rückgabewert: Promise<IDBSQLClient>

openSession-Methode

Öffnet eine Sitzung zwischen DBSQLClient und Datenbank.

Parameter
Anforderung

Geben Sie Folgendes ein: OpenSessionRequest

Ein Satz optionaler Parameter zum Angeben des anfänglichen Schemas und Katalogs.

Beispiel:


const session = await client.openSession(
{initialCatalog: 'catalog'}
);

Rückgabewert: Promise<IDBSQLSession>

getClient-Methode

Gibt das interne Thrift-Objekt „TCLIService.Client“ zurück. Muss aufgerufen werden, nachdem DBSQLClient die Verbindung hergestellt hat.

Keine Parameter

Gibt TCLIService.Client zurück

close-Methode

Schließt die Verbindung mit der Datenbank und gibt alle zugeordneten Ressourcen auf dem Server frei. Jegliche zusätzlichen Aufrufe dieses Clients lösen einen Fehler aus.

Keine Parameter.

Kein Rückgabewert.

DBSQLSession-Klasse

DBSQLSessions werden in erster Linie für die Ausführung von Anweisungen für die Datenbank sowie für verschiedene Metadatenabrufvorgänge verwendet.

Methoden
executeStatement-Methode

Führt eine Anweisung mit den angegebenen Optionen aus.

Parameter
statement

Geben Sie Folgendes ein: str

Die Anweisung, die ausgeführt werden soll.
options

Geben Sie Folgendes ein: ExecuteStatementOptions

Ein Satz optionaler Parameter zum Bestimmen des Abfragetimeouts und der maximalen Zeilenanzahl für direkte Ergebnisse sowie zum Festlegen, ob die Abfrage asynchron ausgeführt werden soll. maxRows ist standardmäßig auf 10.000 festgelegt. Wenn maxRows auf NULL festgelegt ist, wird der Vorgang mit deaktiviertem Feature für direkte Ergebnisse ausgeführt.

Beispiel:


const session = await client.openSession(
{initialCatalog: 'catalog'}
);

queryOperation = await session.executeStatement(
'SELECT "Hello, World!"', { runAsync: true }
);

Rückgabewert: Promise<IOperation>

close-Methode

Schließt die Sitzung. Muss nach der Verwendung der Sitzung ausgeführt werden.

Keine Parameter.

Kein Rückgabewert.

getId-Methode

Gibt die GUID der Sitzung zurück.

Keine Parameter.

Rückgabewert: str

getTypeInfo-Methode

Gibt Informationen zu unterstützten Datentypen zurück.

Parameter
Anforderung

Geben Sie Folgendes ein: TypeInfoRequest

Anforderungsparameter.

Rückgabewert: Promise<IOperation>

getCatalogs-Methode

Ruft eine Liste von Katalogen ab.

Parameter
Anforderung

Geben Sie Folgendes ein: CatalogsRequest

Anforderungsparameter.

Rückgabewert: Promise<IOperation>

getSchemas-Methode

Ruft eine Liste von Schemas ab.

Parameter
Anforderung

Geben Sie Folgendes ein: SchemasRequest

Anforderungsparameter. Die Felder catalogName und schemaName können zu Filterzwecken verwendet werden.

Rückgabewert: Promise<IOperation>

getTables-Methode

Ruft eine Liste von Tabellen ab.

Parameter
Anforderung

Geben Sie Folgendes ein: TablesRequest

Anforderungsparameter. Die Felder catalogName, schemaName und
tableName können zum Filtern verwendet werden.

Rückgabewert: Promise<IOperation>

getFunctions-Methode

Ruft eine Liste von Tabellen ab.

Parameter
Anforderung

Geben Sie Folgendes ein: FunctionsRequest

Anforderungsparameter. Das Feld functionName ist erforderlich.

Rückgabewert: Promise<IOperation>

getPrimaryKeys-Methode

Ruft eine Liste von Primärschlüsseln ab.

Parameter
Anforderung

Geben Sie Folgendes ein: PrimaryKeysRequest

Anforderungsparameter. Die Felder schemaName und tableName sind erforderlich.

Rückgabewert: Promise<IOperation>

getCrossReference-Methode

Ruft Informationen zu Fremdschlüsseln zwischen zwei Tabellen ab.

Parameter
Anforderung

Geben Sie Folgendes ein: CrossReferenceRequest

Anforderungsparameter. Die Namen für „Schema“, „Parent“ und „Catalog“ müssen für beide Tabellen angegeben werden.

Rückgabewert: Promise<IOperation>

DBSQLOperation-Klasse

DBSQLOperations werden von DBSQLSessions erstellt und können verwendet werden, um die Ergebnisse von Anweisungen abzurufen und deren Ausführung zu überprüfen. Daten werden mit den Funktionen fetchChunk und fetchAll abgerufen.

Methoden
getId-Methode

Gibt die GUID des Vorgangs zurück.

Keine Parameter.

Rückgabewert: str

fetchAll-Methode

Wartet auf den Abschluss des Vorgangs und ruft dann alle Zeilen aus dem Vorgang ab.

Parameter: keine

Rückgabewert: Promise<Array<object>>

fetchChunk-Methode

Wartet auf den Abschluss des Vorgangs und ruft dann Zeilen bis zu einer angegebenen Anzahl aus dem Vorgang ab.

Parameter
options

Geben Sie Folgendes ein: FetchOptions

Zum Abrufen verwendete Optionen. Derzeit ist maxRows die einzige Option und entspricht der maximalen Anzahl von Datenobjekten, die in einem bestimmten Array zurückgegeben werden sollen.

Rückgabewert: Promise<Array<object>>

close-Methode

Schließt die Verbindung und gibt alle zugeordneten Ressourcen frei. Muss ausgeführt werden, nachdem der Vorgang nicht mehr verwendet wird.

Keine Parameter.

Kein Rückgabewert.