Udostępnij za pośrednictwem


Sterownik SQL usługi Databricks dla Node.js

Sterownik SQL usługi Databricks dla Node.js to biblioteka Node.js, która umożliwia uruchamianie poleceń SQL w zasobach obliczeniowych usługi Azure Databricks za pomocą kodu JavaScript.

Wymagania

  • Maszyna deweloperna z systemem Node.js w wersji 14 lub nowszej. Aby wydrukować zainstalowaną wersję Node.js, uruchom polecenie node -v. Aby zainstalować różne wersje Node.js i korzystać z nich, możesz użyć narzędzi, takich jak Node Version Manager (nvm).

  • Menedżer pakietów Node (npm). Nowsze wersje Node.js już obejmują npm. Aby sprawdzić, czy npm jest zainstalowana, uruchom polecenie npm -v. W razie potrzeby, aby zainstalować npm, możesz postępować zgodnie z instrukcjami, takimi jak te pod Pobierz i zainstaluj npm.

  • Pakiet @databricks/sql z narzędzia npm. Aby zainstalować @databricks/sql pakiet w projekcie Node.js jako zależność, uruchom npm następujące polecenie z tego samego katalogu, który zawiera projekt:

    npm i @databricks/sql
    
  • Jeśli chcesz zainstalować i używać języka TypeScript w swoim projekcie Node.js, użyj następujących poleceń, uruchamiając je w katalogu, w którym znajduje się Twój projekt:

    npm i -D typescript
    npm i -D @types/node
    
  • Istniejący klaster lub magazyn SQL.

  • Wartość Nazwy hosta serwera i Ścieżki HTTP dla istniejącego klastra lub magazynu SQL.

Uwierzytelnianie

Sterownik SQL usługi Databricks dla Node.js obsługuje następujące typy uwierzytelniania usługi Azure Databricks:

Sterownik SQL usługi Databricks dla Node.js nie obsługuje jeszcze następujących typów uwierzytelniania usługi Azure Databricks:

Uwaga

Jako dobre praktyki w zakresie bezpieczeństwa, nie powinno się na stałe kodować wartości zmiennych połączenia w kodzie. Zamiast tego należy pobrać te wartości zmiennych połączenia z bezpiecznej lokalizacji. Na przykład fragmenty kodu i przykłady w tym artykule używają zmiennych środowiskowych.

Uwierzytelnianie osobistego tokenu dostępu usługi Databricks

Aby użyć sterownika SQL usługi Databricks na potrzeby Node.js z uwierzytelnianiem, należy najpierw utworzyć osobisty token dostępu usługi Azure Databricks. Aby uzyskać szczegółowe informacje na temat tego kroku, zobacz Osobiste tokeny dostępu usługi Azure Databricks dla użytkowników obszaru roboczego.

Aby uwierzytelnić sterownik SQL usługi Databricks dla Node.js, użyj następującego fragmentu kodu. W tym fragmencie kodu założono, że ustawiono następujące zmienne środowiskowe:

  • DATABRICKS_SERVER_HOSTNAMEustaw wartość Nazwa hosta serwera dla klastra lub usługi SQL Warehouse.
  • DATABRICKS_HTTP_PATH, ustaw na wartość ścieżka HTTP dla klastra lub magazynu SQL.
  • DATABRICKS_TOKEN, ustawiony jako osobisty token dostępu usługi Azure Databricks.

Aby ustawić zmienne środowiskowe, zapoznaj się z dokumentacją systemu operacyjnego.

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

Uwierzytelnianie typu użytkownik-komputer (U2M) OAuth

Sterownik SQL usługi Databricks dla Node.js w wersji 1.8.0 lub nowszej obsługuje uwierzytelnianie OAuth użytkownik-maszyna (U2M).

Aby uwierzytelnić sterownik SQL usługi Databricks dla Node.js przy użyciu uwierzytelniania OAuth U2M, użyj następującego fragmentu kodu. W tym fragmencie kodu założono, że ustawiono następujące zmienne środowiskowe:

  • DATABRICKS_SERVER_HOSTNAMEustaw wartość Nazwa hosta serwera dla klastra lub usługi SQL Warehouse.
  • DATABRICKS_HTTP_PATH, ustaw na wartość Ścieżki HTTP dla klastra lub magazynu SQL.

Aby ustawić zmienne środowiskowe, zapoznaj się z dokumentacją systemu operacyjnego.

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

Uwierzytelnianie maszyny do maszyny OAuth (M2M)

Sterownik SQL usługi Databricks dla Node.js w wersji 1.8.0 lub nowszej obsługuje uwierzytelnianie między maszynami OAuth (U2M).

Aby użyć sterownika SQL usługi Databricks na potrzeby Node.js z uwierzytelnianiem OAuth M2M, należy wykonać następujące czynności:

  1. Utwórz jednostkę usługi Azure Databricks w obszarze roboczym usługi Azure Databricks i utwórz wpis tajny OAuth dla tej jednostki usługi.

    Aby utworzyć jednostkę usługi i jej tajny klucz OAuth, zobacz Autoryzuj nienadzorowany dostęp do zasobów Azure Databricks przy użyciu jednostki usługi z OAuth. Zanotuj wartość UUID lub Identyfikatora aplikacji dla głównego użytkownika usługi, oraz wartość Tajnego dla sekretu OAuth tego głównego użytkownika usługi.

  2. Nadaj jednostce usługi dostęp do klastra lub magazynu. Zobacz Uprawnienia obliczeniowe lub Zarządzanie usługą SQL Warehouse.

Aby uwierzytelnić sterownik SQL usługi Databricks dla Node.js, użyj następującego fragmentu kodu. W tym fragmencie kodu założono, że ustawiono następujące zmienne środowiskowe:

  • DATABRICKS_SERVER_HOSTNAMEustaw wartość Nazwa hosta serwera dla klastra lub usługi SQL Warehouse.
  • DATABRICKS_HTTP_PATH, ustaw wartość dla ścieżki HTTP klastra lub SQL Warehouse.
  • DATABRICKS_CLIENT_ID, ustaw na wartość UUID jednostki usługi lub ID aplikacji.
  • DATABRICKS_CLIENT_SECRET, ustaw na wartość tajną dla sekretu OAuth konta usługi.

Aby ustawić zmienne środowiskowe, zapoznaj się z dokumentacją systemu operacyjnego.

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

Uwierzytelnianie tokenu Microsoft Entra ID

Aby użyć sterownika SQL usługi Databricks dla Node.js z uwierzytelnianiem tokenu identyfikatora Entra firmy Microsoft, należy podać sterownik SQL usługi Databricks dla Node.js z tokenem identyfikatora Entra firmy Microsoft. Aby utworzyć token dostępu microsoft Entra ID, wykonaj następujące czynności:

Tokeny identyfikatora Entra firmy Microsoft mają domyślny okres istnienia około 1 godziny. Aby utworzyć nowy token identyfikatora Entra firmy Microsoft, powtórz ten proces.

Aby uwierzytelnić sterownik SQL usługi Databricks dla Node.js, użyj następującego fragmentu kodu. W tym fragmencie kodu założono, że ustawiono następujące zmienne środowiskowe:

  • DATABRICKS_SERVER_HOSTNAMEustaw wartość Nazwa hosta serwera dla klastra lub usługi SQL Warehouse.
  • DATABRICKS_HTTP_PATH, ustaw na wartość ścieżka HTTP dla klastra lub magazynu SQL.
  • DATABRICKS_TOKEN, ustawione na token Microsoft Entra ID.

Aby ustawić zmienne środowiskowe, zapoznaj się z dokumentacją systemu operacyjnego.

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

Zapytanie danych

W poniższym przykładzie kodu pokazano, jak wywołać sterownik SQL usługi Databricks dla Node.js w celu uruchomienia podstawowego zapytania SQL w zasobie obliczeniowym usługi Azure Databricks. To polecenie zwraca dwa pierwsze wiersze z tabeli trips w schemacie nyctaxi katalogu samples.

Uwaga

W poniższym przykładzie kodu pokazano, jak używać osobistego tokenu dostępu usługi Azure Databricks do uwierzytelniania. Aby zamiast tego użyć innych dostępnych typów uwierzytelniania usługi Azure Databricks, zobacz Uwierzytelnianie.

Ten przykład kodu pobiera wartości zmiennych połączenia token, server_hostname i http_path z zestawu zmiennych środowiskowych usługi Azure Databricks. Te zmienne środowiskowe mają następujące nazwy zmiennych środowiskowych:

  • DATABRICKS_TOKEN, który reprezentuje Twój osobisty token dostępu usługi Azure Databricks zgodnie z wymaganiami.
  • DATABRICKS_SERVER_HOSTNAME, który reprezentuje wartość Nazwa hosta serwera z wymagań.
  • DATABRICKS_HTTP_PATH, który reprezentuje wartość ścieżki HTTP z wymagań.

Możesz użyć innych metod pobierania tych wartości zmiennych połączenia. Używanie zmiennych środowiskowych jest tylko jednym z wielu podejść.

W poniższym przykładzie kodu pokazano, jak wywołać łącznik SQL usługi Databricks dla Node.js w celu uruchomienia podstawowego polecenia SQL w klastrze lub usłudze SQL Warehouse. To polecenie zwraca dwa pierwsze wiersze z trips tabeli.

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

Wyjście:

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

Sesje

Wszystkie IDBSQLSession metody, które zwracają IOperation obiekty w dokumentacji API, mają następujące wspólne parametry wpływające na ich działanie:

  • Ustawienie runAsync powoduje uruchomienie trybu asynchronicznego w true. IDBSQLSession metody umieszczają operacje w kolejce i zwracają je tak szybko, jak to możliwe. Bieżący stan zwróconego IOperation obiektu może się różnić, a klient jest odpowiedzialny za sprawdzenie jego stanu przed użyciem zwróconego IOperationobiektu . Zobacz Operacje. Ustawienie runAsync na false wartość oznacza, że IDBSQLSession metody oczekują na zakończenie operacji. Databricks zaleca zawsze ustawianie runAsync na true.
  • Ustawienie maxRows wartości innej niż null umożliwia bezpośrednie wyniki. W przypadku bezpośrednich wyników serwer próbuje poczekać na zakończenie operacji, a następnie pobrać część danych. W zależności od tego, ile pracy serwer mógł wykonać w zdefiniowanym czasie, IOperation obiekty są zwracane w pewnym stanie pośrednim zamiast w stanie oczekiwania. Bardzo często wszystkie metadane i wyniki zapytania są zwracane w ramach jednego żądania do serwera. Serwer używa maxRows do określenia, ile rekordów może zwrócić natychmiast. Jednak rzeczywisty fragment może mieć inny rozmiar; zobacz IDBSQLSession.fetchChunk. Wyniki bezpośrednie są domyślnie włączone. Usługa Databricks odradza wyłączanie wyników bezpośrednich.

Operacje

Zgodnie z opisem w temacie Sesje, obiekty zwracane przez metody sesji IOperation w Odwołaniu API nie są w pełni wypełniane. Powiązana operacja serwera może nadal trwać, na przykład oczekiwanie na uruchomienie usługi Databricks SQL Warehouse, uruchomienie zapytania lub pobranie danych. Klasa IOperation ukrywa te szczegóły przed użytkownikami. Na przykład metody, takie fetchAlljak , fetchChunk, i getSchema oczekują wewnętrznie na zakończenie operacji, a następnie zwracają wyniki. Możesz użyć IOperation.finished() metody , aby jawnie poczekać na zakończenie operacji. Te metody przyjmują wywołanie zwrotne, które jest okresowo wywoływane podczas oczekiwania na zakończenie operacji. Ustawienie opcji progress na true powoduje próbę zażądania dodatkowych danych postępu z serwera i przekazania ich do tego wywołania zwrotnego.

Metody close i cancel można wywołać w dowolnym momencie. Po wywołaniu natychmiast unieważniają IOperation obiekt; wszystkie oczekujące wywołania, takie jak fetchAll, fetchChunk, i getSchema, są natychmiast anulowane, a zwracany jest błąd. W niektórych przypadkach operacja serwera mogła już zostać ukończona, a cancel metoda ma wpływ tylko na klienta.

Metoda fetchAll wywołuje fetchChunk wewnętrznie i zbiera wszystkie dane do tablicy. Chociaż jest to wygodne, może to spowodować błędy braku pamięci w przypadku użycia w dużych zestawach danych. fetchAll opcje są zwykle przekazywane do fetchChunk.

Pobieranie fragmentów danych

Pobieranie fragmentów danych używa następującego wzorca kodu:

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

Metoda fetchChunk w dokumentacji interfejsu API przetwarza dane w małych częściach, aby zmniejszyć zużycie pamięci. fetchChunk najpierw oczekuje na ukończenie operacji, jeśli nie zostały jeszcze ukończone, a następnie wywołuje wywołanie zwrotne podczas cyklu oczekiwania, a następnie pobiera następny fragment danych.

Możesz użyć maxRows opcji , aby określić żądany rozmiar fragmentu. Jednak zwrócony fragment może mieć inny rozmiar, mniejszy lub nawet czasami większy. fetchChunk nie próbuje prefetchować danych wewnętrznie, aby podzielić je na żądane fragmenty. Wysyła opcję maxRows do serwera i zwraca to, co zwraca serwer. Nie należy mylić tej maxRows opcji z tą w IDBSQLSession. maxRows przekazana do fetchChunk definiuje rozmiar każdego fragmentu i nie wykonuje żadnych innych czynności.

Zarządzanie plikami w wolumenach Unity Catalog

Sterownik SQL usługi Databricks umożliwia zapisywanie plików lokalnych w woluminach Unity Catalog , pobieranie plików z woluminów i usuwanie plików z woluminów, jak pokazano w poniższym przykładzie:

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

Konfigurowanie rejestrowania

Rejestrator zawiera informacje dotyczące debugowania problemów z łącznikiem. Wszystkie DBSQLClient obiekty są tworzone za pomocą rejestratora, który drukuje do konsoli, ale przekazując niestandardowy rejestrator, można wysłać te informacje do pliku. W poniższym przykładzie pokazano, jak skonfigurować rejestrator i zmienić jego poziom.

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

Aby uzyskać dodatkowe przykłady, zobacz folder examples w repozytorium databricks/databricks-sql-nodejs w witrynie GitHub.

Testowanie

Aby przetestować kod, możesz użyć platform testowych JavaScript, takich jak Jest. Aby przetestować kod w symulowanych warunkach bez wywoływania punktów końcowych interfejsu API REST usługi Azure Databricks lub zmieniania stanu kont lub obszarów roboczych usługi Azure Databricks, możesz użyć wbudowanych struktur pozorowania w usłudze Jest.

Na przykład, biorąc pod uwagę następujący plik o nazwie helpers.js, zawierający funkcję getDBSQLClientWithPAT, która używa osobistego tokenu dostępu usługi Azure Databricks, aby zwrócić połączenie z obszarem roboczym usługi Azure Databricks, funkcję getAllColumnsFromTable, która korzysta z połączenia, aby pobrać określoną liczbę wierszy danych z określonej tabeli (na przykład tabeli trips w schemacie samples wykazu nyctaxi), oraz funkcję printResults do drukowania zawartości wierszy danych:

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

I biorąc pod uwagę następujący plik o nazwie main.js, który wywołuje funkcję getDBSQLClientWithPAT, getAllColumnsFromTable oraz 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);
  });

Poniższy plik o nazwie helpers.test.js testuje, czy getAllColumnsFromTable funkcja zwraca oczekiwaną odpowiedź. Zamiast tworzyć rzeczywiste połączenie z docelowym obszarem roboczym, ten test wyśmiewa DBSQLClient obiekt. Test wyśmiewa również niektóre dane zgodne ze schematem i wartościami, które znajdują się w rzeczywistych danych. Test zwraca symulowane dane za pośrednictwem mockowanego połączenia, a następnie sprawdza, czy jedna z wartości w wierszach symulowanych danych jest zgodna z oczekiwaną wartością.

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

W przypadku języka TypeScript powyższy kod wygląda podobnie. W przypadku testowania w języku TypeScript użyj ts-jest.

Dodatkowe zasoby

Referencja API

Klasy

Klasa DBSQLClient

Główny punkt wejścia do interakcji z bazą danych.

Metody
connect metoda

Otwiera połączenie z bazą danych.

Parametry
Opcje
Typ: ConnectionOptions
Zestaw opcji używanych do nawiązywania połączenia z bazą danych.
Należy wypełnić pola host, path oraz inne wymagane. Zobacz Uwierzytelnianie.
Przykład:
const client: DBSQLClient = new DBSQLClient();
client.connect(
{
host: serverHostname,
path: httpPath,
// ...
}
)

Zwroty: Promise<IDBSQLClient>

openSession metoda

Otwiera sesję między elementem DBSQLClient i bazą danych.

Parametry
prośba
Typ: OpenSessionRequest
Zestaw parametrów opcjonalnych do określania początkowego schematu i katalogu początkowego
Przykład:
const session = await client.openSession(
{initialCatalog: 'catalog'}
);

Zwroty: Promise<IDBSQLSession>

getClient metoda

Zwraca wewnętrzny obiekt TCLIService.Client. Należy wykonać po nawiązaniu połączenia z DBSQLClient.

Brak parametrów

Zwraca TCLIService.Client

close metoda

Zamyka połączenie z bazą danych i zwalnia wszystkie skojarzone zasoby na serwerze. Wszelkie dodatkowe wywołania tego klienta będą zgłaszać błąd.

Brak parametrów.

Brak wartości zwracanej.

Klasa DBSQLSession

DBSQLSessions są używane głównie do wykonywania instrukcji w bazie danych oraz do różnych operacji pobierania metadanych.

Metody
executeStatement metoda

Wykonuje instrukcję z podanymi opcjami.

Parametry
wypowiedź
Typ: str
Polecenie do wykonania.
Opcje
Typ: ExecuteStatementOptions
Zestaw opcjonalnych parametrów do określania limitu czasu zapytania, maksymalnej liczby wierszy dla wyników bezpośrednich oraz tego, czy zapytanie ma być uruchamiane asynchronicznie. Domyślnie maxRows ustawiono wartość 10000. Jeśli maxRows ustawiono wartość null, operacja zostanie uruchomiona z wyłączoną funkcją wyników bezpośrednich.
Przykład:
const session = await client.openSession(
{initialCatalog: 'catalog'}
);
queryOperation = await session.executeStatement(
'SELECT "Hello, World!"', { runAsync: true }
);

Zwroty: Promise<IOperation>

close metoda

Zamyka sesję. Należy wykonać po zakończeniu sesji.

Brak parametrów.

Brak wartości zwracanej.

getId metoda

Zwraca identyfikator GUID sesji.

Brak parametrów.

Zwroty: str

getTypeInfo metoda

Zwraca informacje o obsługiwanych typach danych.

Parametry
prośba
Typ: TypeInfoRequest
Parametry żądania.

Zwroty: Promise<IOperation>

getCatalogs metoda

Pobiera listę katalogów.

Parametry
żądanie
Typ: CatalogsRequest
Parametry żądania.

Zwroty: Promise<IOperation>

getSchemas metoda

Pobiera listę schematów.

Parametry
prośba
Typ: SchemasRequest
Parametry żądania. Pola catalogName i schemaName mogą być używane do celów filtrowania.

Zwroty: Promise<IOperation>

getTables metoda

Pobiera listę tabel.

Parametry
prośba
Typ: TablesRequest
Parametry żądania. Pola catalogName i schemaName
tableName może służyć do filtrowania.

Zwroty: Promise<IOperation>

getFunctions metoda

Pobiera listę tabel.

Parametry
żądanie
Typ: FunctionsRequest
Parametry żądania. Pole functionName jest wymagane.

Zwroty: Promise<IOperation>

getPrimaryKeys metoda

Pobiera listę kluczy podstawowych.

Parametry
żądanie
Typ: PrimaryKeysRequest
Parametry żądania. Pola schemaName i tableName są wymagane.

Zwroty: Promise<IOperation>

getCrossReference metoda

Pobiera informacje o kluczach obcych między dwiema tabelami.

Parametry
żądanie
Typ: CrossReferenceRequest
Parametry żądania. Nazwa schematu, elementu nadrzędnego i wykazu musi być określona dla obu tabel.

Zwroty: Promise<IOperation>

Klasa DBSQLOperation

Operacje DBSQL Są tworzone przez narzędzia DBSQLSessions i mogą służyć do pobierania wyników instrukcji i sprawdzania ich wykonywania. Dane są pobierane za pośrednictwem funkcji fetchChunk i fetchAll.

Metody
getId metoda

Zwraca identyfikator GUID operacji.

Brak parametrów.

Zwroty: str

fetchAll metoda

Czeka na zakończenie operacji, a następnie pobiera wszystkie wiersze z operacji.

Parametry: Brak

Zwroty: Promise<Array<object>>

fetchChunk metoda

Czeka na zakończenie operacji, a następnie pobiera maksymalnie określoną liczbę wierszy z operacji.

Parametry
Opcje
Typ: FetchOptions
Opcje używane do pobierania. Obecnie jedyną opcją jest maxRows, która odpowiada maksymalnej liczbie obiektów danych zwracanych w dowolnej tablicy.

Zwroty: Promise<Array<object>>

close metoda

Zamyka operację i zwalnia wszystkie skojarzone zasoby. Należy wykonać po zakończeniu korzystania z operacji.

Brak parametrów.

Brak wartości zwracanej.