Partilhar via


Databricks SQL Driver para Node.js

O Databricks SQL Driver for Node.js é uma biblioteca de Node.js que permite usar o código JavaScript para executar comandos SQL nos recursos de computação do Azure Databricks.

Requisitos

  • Uma máquina de desenvolvimento executando Node.js, versão 14 ou superior. Para imprimir a versão instalada do Node.js, execute o comando node -v. Para instalar e usar diferentes versões do Node.js, você pode usar ferramentas como o Node Version Manager (nvm).

  • Gerenciador de pacotes de nó (npm). Versões posteriores do Node.js já incluem npmo . Para verificar se npm está instalado, execute o comando npm -v. Para instalar npm , se necessário, você pode seguir instruções como as de Download e instalar o npm.

  • O pacote @databricks/sql do npm. Para instalar o @databricks/sql pacote em seu projeto Node.js como uma dependência, use npm para executar o seguinte comando de dentro do mesmo diretório que seu projeto:

    npm i @databricks/sql
    
  • Se você quiser instalar e usar o TypeScript em seu projeto Node.js como devDependencies, use npm para executar os seguintes comandos de dentro do mesmo diretório do seu projeto:

    npm i -D typescript
    npm i -D @types/node
    
  • Um cluster ou armazém SQL existente.

  • O valor Nome do host do servidor e Caminho HTTP para o cluster existente ou o SQL warehouse.

Autenticação

O Databricks SQL Driver for Node.js dá suporte aos seguintes tipos de autenticação do Azure Databricks:

O Databricks SQL Driver for Node.js ainda não oferece suporte aos seguintes tipos de autenticação do Azure Databricks:

Nota

Como prática recomendada de segurança, você não deve codificar valores de variáveis de conexão em seu código. Em vez disso, você deve recuperar esses valores de variáveis de conexão de um local seguro. Por exemplo, os trechos de código e exemplos neste artigo usam variáveis de ambiente.

Autenticação de token de acesso pessoal Databricks

Para usar o Databricks SQL Driver para Node.js com autenticação, você deve primeiro criar um token de acesso pessoal do Azure Databricks. Para obter detalhes sobre esta etapa, consulte Tokens de acesso pessoal do Azure Databricks para usuários do espaço de trabalho.

Para autenticar o Databricks SQL Driver for Node.js, use o seguinte trecho de código. Este trecho pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.
  • DATABRICKS_TOKEN, definido como o token de acesso pessoal do Azure Databricks.

Para definir variáveis de ambiente, consulte a documentação do seu sistema operacional.

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

Autenticação OAuth user-to-machine (U2M)

O Databricks SQL Driver para Node.js versões 1.8.0 e superiores suporta autenticação OAuth user-to-machine (U2M).

Para autenticar o Databricks SQL Driver for Node.js com autenticação OAuth U2M, use o seguinte trecho de código. Este trecho pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.

Para definir variáveis de ambiente, consulte a documentação do seu sistema operacional.

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

Autenticação OAuth máquina-a-máquina (M2M)

O Databricks SQL Driver para Node.js versões 1.8.0 e superiores suporta autenticação OAuth máquina-a-máquina (U2M).

Para usar o Databricks SQL Driver para Node.js com autenticação OAuth M2M, você deve fazer o seguinte:

  1. Crie uma entidade de serviço do Azure Databricks em seu espaço de trabalho do Azure Databricks e crie um segredo OAuth para essa entidade de serviço.

    Para criar a entidade de serviço e seu segredo OAuth, consulte Autenticar o acesso ao Azure Databricks com uma entidade de serviço usando OAuth (OAuth M2M). Anote o valor UUID ou ID do aplicativo da entidade de serviço e o valor Secret do segredo OAuth da entidade de serviço.

  2. Dê à entidade de serviço acesso ao seu cluster ou depósito. Consulte Permissões de computação ou Gerenciar um armazém SQL.

Para autenticar o Databricks SQL Driver for Node.js, use o seguinte trecho de código. Este trecho pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.
  • DATABRICKS_CLIENT_ID, definido como o valor UUID ou ID do aplicativo da entidade de serviço.
  • DATABRICKS_CLIENT_SECRET, definido como o valor Secret para o segredo OAuth da entidade de serviço.

Para definir variáveis de ambiente, consulte a documentação do seu sistema operacional.

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

Autenticação de token do Microsoft Entra ID

Para usar o Databricks SQL Driver for Node.js com a autenticação de token do Microsoft Entra ID, você deve fornecer o Databricks SQL Driver for Node.js com o token do Microsoft Entra ID. Para criar um token de acesso do Microsoft Entra ID, faça o seguinte:

Os tokens Microsoft Entra ID têm um tempo de vida padrão de cerca de 1 hora. Para criar um novo token de ID do Microsoft Entra, repita este processo.

Para autenticar o Databricks SQL Driver for Node.js, use o seguinte trecho de código. Este trecho pressupõe que você tenha definido as seguintes variáveis de ambiente:

  • DATABRICKS_SERVER_HOSTNAMEdefinido como o valor Nome do host do servidor para seu cluster ou SQL warehouse.
  • DATABRICKS_HTTP_PATH, definido como o valor Caminho HTTP para seu cluster ou SQL warehouse.
  • DATABRICKS_TOKEN, definido como o token de ID do Microsoft Entra.

Para definir variáveis de ambiente, consulte a documentação do seu sistema operacional.

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

Consultar os dados

O exemplo de código a seguir demonstra como chamar o Databricks SQL Driver for Node.js para executar uma consulta SQL básica em um recurso de computação do Azure Databricks. Este comando retorna as duas primeiras linhas da trips tabela no samples esquema do nyctaxi catálogo.

Nota

O exemplo de código a seguir demonstra como usar um token de acesso pessoal do Azure Databricks para autenticação. Para usar outros tipos de autenticação disponíveis do Azure Databricks, consulte Autenticação.

Este exemplo de código recupera os tokenvalores da variável , server_hostname e http_path connection de um conjunto de variáveis de ambiente do Azure Databricks. Essas variáveis de ambiente têm os seguintes nomes de variáveis de ambiente:

  • DATABRICKS_TOKEN, que representa seu token de acesso pessoal do Azure Databricks a partir dos requisitos.
  • DATABRICKS_SERVER_HOSTNAME, que representa o valor Server Hostname dos requisitos.
  • DATABRICKS_HTTP_PATH, que representa o valor do caminho HTTP dos requisitos.

Você pode usar outras abordagens para recuperar esses valores de variáveis de conexão. O uso de variáveis de ambiente é apenas uma abordagem entre muitas.

O exemplo de código a seguir demonstra como chamar o Databricks SQL Connector para Node.js executar um comando SQL básico em um cluster ou armazém SQL. Este comando retorna as duas primeiras linhas da trips tabela.

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

Saída:

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

Sessões

Todos os IDBSQLSession métodos que retornam IOperation objetos na Referência de API têm os seguintes parâmetros comuns que afetam seu comportamento:

  • Configuração runAsync para iniciar o modo assíncrono true . IDBSQLSession Os métodos colocam as operações na fila e retornam o mais rápido possível. O estado atual do objeto retornado IOperation pode variar, e o cliente é responsável por verificar seu status antes de usar o objeto retornado IOperation. Consulte Operações. A configuração runAsync significa false que IDBSQLSession os métodos aguardam a conclusão das operações. Databricks recomenda sempre definir runAsync como true.
  • A configuração maxRows como um valor não nulo permite resultados diretos. Com resultados diretos, o servidor tenta aguardar a conclusão das operações e, em seguida, busca uma parte dos dados. Dependendo de quanto trabalho o servidor foi capaz de concluir dentro do tempo definido, IOperation os objetos retornam em algum estado intermediário em vez de em algum estado pendente. Muitas vezes, todos os metadados e resultados da consulta são retornados dentro de uma única solicitação para o servidor. O servidor usa maxRows para determinar quantos registros ele pode retornar imediatamente. No entanto, o pedaço real pode ser de um tamanho diferente; veja IDBSQLSession.fetchChunk. Os resultados diretos são ativados por padrão. A Databricks recomenda não desativar os resultados diretos.

Operações

Conforme descrito em Sessões, IOperation os objetos retornados por IDBSQLSession métodos de sessão na Referência de API não são totalmente preenchidos. A operação do servidor relacionado ainda pode estar em andamento, como aguardar o início do armazém SQL do Databricks, executar a consulta ou buscar os dados. A IOperation classe oculta esses detalhes dos usuários. Por exemplo, métodos como fetchAll, fetchChunke aguarde getSchema internamente a conclusão das operações e, em seguida, retorne os resultados. Você pode usar o IOperation.finished() método para aguardar explicitamente a conclusão das operações. Esses métodos recebem um retorno de chamada que é chamado periodicamente enquanto aguarda a conclusão das operações. Definir a progress opção para true tentar solicitar dados de progresso adicionais do servidor e passá-los para esse retorno de chamada.

Os close métodos e cancel podem ser chamados a qualquer momento. Quando chamados, eles invalidam imediatamente o IOperation objeto, todas as chamadas pendentes, como fetchAll, fetchChunke getSchema são imediatamente canceladas e um erro é retornado. Em alguns casos, a operação do servidor pode já ter sido concluída e o cancel método afeta apenas o cliente.

O fetchAll método chama fetchChunk internamente e coleta todos os dados em uma matriz. Embora isso seja conveniente, pode causar erros de falta de memória quando usado em grandes conjuntos de dados. fetchAll as opções são normalmente passadas para fetchChunk.

Buscar blocos de dados

A busca de blocos de dados usa o seguinte padrão de código:

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

O fetchChunk método na referência da API processa dados em pequenas porções para reduzir o consumo de memória. fetchChunk Primeiro, aguarda a conclusão das operações se ainda não tiverem sido concluídas, depois chama um retorno de chamada durante o ciclo de espera e, em seguida, busca o próximo bloco de dados.

Você pode usar a maxRows opção para especificar o tamanho de bloco desejado. No entanto, o pedaço retornado pode ter um tamanho diferente, menor ou até mesmo às vezes maior. fetchChunk não tenta pré-buscar dados internamente, a fim de fatiá-los nas partes solicitadas. Ele envia a opção para o maxRows servidor e retorna o que o servidor retorna. Não confunda esta maxRows opção com a do IDBSQLSession. maxRows passado para fetchChunk define o tamanho de cada pedaço e não faz mais nada.

Gerenciar arquivos em volumes do Catálogo Unity

O Databricks SQL Driver permite que você escreva arquivos locais em volumes do Catálogo Unity, baixe arquivos de volumes e exclua arquivos de volumes, conforme mostrado no exemplo a seguir:

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

Configurar registo

O registrador fornece informações para problemas de depuração com o conector. Todos os DBSQLClient objetos são instanciados com um registrador que imprime no console, mas passando um registrador personalizado, você pode enviar essas informações para um arquivo. O exemplo a seguir mostra como configurar um registrador e alterar seu nível.

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

Para obter exemplos adicionais, consulte a pasta de exemplos no repositório databricks/databricks-sql-nodejs no GitHub.

Testar

Para testar seu código, você pode usar estruturas de teste JavaScript como Jest. Para testar seu código em condições simuladas sem chamar pontos de extremidade da API REST do Azure Databricks ou alterar o estado de suas contas ou espaços de trabalho do Azure Databricks, você pode usar as estruturas simuladas internas do Jest.

Por exemplo, dado o seguinte arquivo chamado helpers.js contendo uma getDBSQLClientWithPAT função que usa um token de acesso pessoal do Azure Databricks para retornar uma conexão a um espaço de trabalho do Azure Databricks, uma getAllColumnsFromTable função que usa a conexão para obter o número especificado de linhas de dados da tabela especificada (por exemplo, a trips tabela no samples esquema do catálogo nyctaxi ) e uma printResults função para imprimir o conteúdo das linhas de dados:

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

E dado o seguinte arquivo chamado main.js getDBSQLClientWithPATgetAllColumnsFromTable, e printResults funções:

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

O arquivo a seguir chamado helpers.test.js testa se a getAllColumnsFromTable função retorna a resposta esperada. Em vez de criar uma conexão real com o espaço de trabalho de destino, esse teste simula um DBSQLClient objeto. O teste também simula alguns dados que estão em conformidade com o esquema e os valores que estão nos dados reais. O teste retorna os dados simulados por meio da conexão simulada e, em seguida, verifica se um dos valores das linhas de dados simuladas corresponde ao valor esperado.

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

Para TypeScript, o código anterior é semelhante. Para testes Jest com TypeScript, use ts-jest.

Recursos adicionais

Referência da API

Classes

DBSQLClient Classe

Principal ponto de entrada para interagir com um banco de dados.

Métodos
connect método

Abre uma conexão com o banco de dados.

Parâmetros
Opções

Tipo: ConnectionOptions

O conjunto de opções usado para se conectar ao banco de dados.

Os hostcampos , pathe outros campos obrigatórios devem ser preenchidos. Consulte Autenticação.

Exemplo:


const client: DBSQLClient = new DBSQLClient();

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

Devoluções: Promise<IDBSQLClient>

openSession método

Abre a sessão entre DBSQLClient e o banco de dados.

Parâmetros
solicitar

Tipo: OpenSessionRequest

Um conjunto de parâmetros opcionais para especificar o esquema inicial e o catálogo inicial

Exemplo:


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

Devoluções: Promise<IDBSQLSession>

getClient método

Retorna o objeto interno thrift TCLIService.Client. Deve ser chamado após DBSQLClient ter se conectado.

No parameters

Devoluções TCLIService.Client

close método

Fecha a conexão com o banco de dados e libera todos os recursos associados no servidor. Quaisquer chamadas adicionais para este cliente gerarão erro.

Sem parâmetros.

Sem valor de retorno.

DBSQLSession Classe

DBSQLSessions são usados principalmente para a execução de instruções no databbase, bem como várias operações de busca de metadados.

Métodos
executeStatement método

Executa uma instrução com as opções fornecidas.

Parâmetros
Declaração

Tipo: str

A instrução a ser executada.
Opções

Tipo: ExecuteStatementOptions

Um conjunto de parâmetros opcionais para determinar o tempo limite da consulta, o máximo de linhas para resultados diretos e se a consulta deve ser executada de forma assíncrona. Por padrão maxRows é definido como 10000. Se maxRows estiver definido como null, a operação será executada com o recurso de resultados diretos desativado.

Exemplo:


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

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

Devoluções: Promise<IOperation>

close método

Encerra a sessão. Deve ser feito após o uso da sessão.

Sem parâmetros.

Sem valor de retorno.

getId método

Retorna o GUID da sessão.

Sem parâmetros.

Devoluções: str

getTypeInfo método

Retorna informações sobre tipos de dados suportados.

Parâmetros
solicitar

Tipo: TypeInfoRequest

Parâmetros de solicitação.

Devoluções: Promise<IOperation>

getCatalogs método

Obtém lista de catálogos.

Parâmetros
solicitar

Tipo: CatalogsRequest

Parâmetros de solicitação.

Devoluções: Promise<IOperation>

getSchemas método

Obtém a lista de esquemas.

Parâmetros
solicitar

Tipo: SchemasRequest

Parâmetros de solicitação. Campos catalogName e schemaName pode ser usado para fins de filtragem.

Devoluções: Promise<IOperation>

getTables método

Obtém a lista de tabelas.

Parâmetros
solicitar

Tipo: TablesRequest

Parâmetros de solicitação. Campos catalogName e schemaName e
tableName pode ser usado para filtragem.

Devoluções: Promise<IOperation>

getFunctions método

Obtém a lista de tabelas.

Parâmetros
solicitar

Tipo: FunctionsRequest

Parâmetros de solicitação. Campo functionName obrigatório.

Devoluções: Promise<IOperation>

getPrimaryKeys método

Obtém a lista de chaves primárias.

Parâmetros
solicitar

Tipo: PrimaryKeysRequest

Parâmetros de solicitação. Campos schemaName e tableName são obrigatórios.

Devoluções: Promise<IOperation>

getCrossReference método

Obtém informações sobre chaves estrangeiras entre duas tabelas.

Parâmetros
solicitar

Tipo: CrossReferenceRequest

Parâmetros de solicitação. O nome do esquema, pai e catálogo deve ser especificado para ambas as tabelas.

Devoluções: Promise<IOperation>

DBSQLOperation Classe

DBSQLOperations são criados por DBSQLSessions e podem ser usados para buscar os resultados de instruções e verificar sua execução. Os dados são obtidos através das funções fetchChunk e fetchAll.

Métodos
getId método

Retorna o GUID da operação.

Sem parâmetros.

Devoluções: str

fetchAll método

Aguarda a conclusão da operação e, em seguida, busca todas as linhas da operação.

Parâmetros: Nenhum

Devoluções: Promise<Array<object>>

fetchChunk método

Aguarda a conclusão da operação e, em seguida, obtém até um número especificado de linhas de uma operação.

Parâmetros
Opções

Tipo: FetchOptions

Opções usadas para buscar. Atualmente, a única opção é maxRows, que corresponde ao número máximo de objetos de dados a serem retornados em qualquer matriz.

Devoluções: Promise<Array<object>>

close método

Fecha a operação e libera todos os recursos associados. Deve ser feito depois de não usar mais a operação.

Sem parâmetros.

Sem valor de retorno.