Compartir a través de


Controlador de Databricks SQL para Node.js

El Controlador de Databricks SQL para Node.js es una biblioteca de Node.js que permite usar código de JavaScript para ejecutar comandos SQL en recursos de proceso de Azure Databricks.

Requisitos

  • Una máquina de desarrollo que ejecute Node.js versión 14 o posterior. Para imprimir la versión instalada de Node.js, ejecute el comando node -v. Para instalar y usar diferentes versiones de Node.js, puede usar herramientas como el Administrador de versiones de Node (nvm).

  • Administrador de paquetes de Node (npm). Las versiones posteriores de Node.js ya incluyen npm. Para comprobar si npm está instalado, ejecute el comando npm -v. Para instalar npm si es necesario, puede seguir instrucciones como las que aparecen en Descargar e instalar npm.

  • El paquete @databricks/sql de npm. Para instalar el paquete @databricks/sql en el proyecto de Node.js como una dependencia, use npm para ejecutar el siguiente comando desde el mismo directorio que el proyecto:

    npm i @databricks/sql
    
  • Si quiere instalar y usar TypeScript en el proyecto de Node.js como devDependencies, use npm para ejecutar los siguientes comandos desde el mismo directorio que el proyecto:

    npm i -D typescript
    npm i -D @types/node
    
  • Un clúster o un almacén de SQL existente.

  • El valor de Nombre de host del servidor y Ruta de acceso HTTP del clúster existente o del almacén de SQL.

Autenticación

El controlador Databricks SQL para Node.js admite los siguientes tipos de autenticación de Azure Databricks:

Databricks SQL Driver for Node.js aún no admite los siguientes tipos de autenticación de Azure Databricks:

Nota:

Como procedimiento recomendado de seguridad, no debe codificar de forma rígida los valores de variable de conexión en el código. En su lugar, recupere estos valores de variable de conexión de una ubicación segura. Por ejemplo, los fragmentos de código y ejemplos de este artículo usan variables de entorno.

Autenticación de token de acceso personal de Databricks

Para usar el controlador Databricks SQL para Node.js con la autenticación de token de acceso personal de Azure Databricks, primero debe crear un token de acceso personal de Azure Databricks, como se indica a continuación:

  1. En el área de trabajo de Azure Databricks, haga clic en el nombre de usuario de Azure Databricks en la barra superior y, a continuación, seleccione Configuración en la lista desplegable.
  2. Haga clic en Desarrollador.
  3. Junto a Tokens de acceso, haga clic en Administrar.
  4. Haga clic en Generate new token (Generar nuevo token).
  5. (Opcional) Escriba un comentario que le ayude a identificar este token en el futuro y cambie la duración predeterminada del token de 90 días. Para crear un token sin duración (no recomendado), deje el cuadro Duración (días) vacío (en blanco).
  6. Haga clic en Generar.
  7. Copie el token mostrado en una ubicación segura y, a continuación, haga clic en Listo.

Nota:

Asegúrese de guardar el token copiado en una ubicación segura. No comparta el token copiado con otros usuarios. Si pierde el token copiado, no podrá volver a generar ese mismo token. Debe repetir el procedimiento para crear un nuevo token. Si pierde el token copiado o cree que el token se ha visto comprometido, Databricks recomienda eliminar inmediatamente ese token del área de trabajo haciendo clic en el icono de papelera (Revocar) situado junto al token en la página Tokens de acceso.

Si no puede crear o usar tokens en el área de trabajo, puede deberse a que el administrador del área de trabajo tiene tokens deshabilitados o no le ha concedido permiso para crear o usar tokens. Consulte el administrador del área de trabajo o lo siguiente:

Para autenticar el controlador Databricks SQL para Node.js, use el siguiente fragmento de código. En este fragmento, se da por supuesto que ha establecido las siguientes variables de entorno:

  • DATABRICKS_SERVER_HOSTNAMEestablecido en el valor de Nombre de host del servidor del clúster o almacén de SQL.
  • DATABRICKS_HTTP_PATH, establecido en el valor de Ruta de acceso HTTP del clúster o almacén del SQL.
  • DATABRICKS_TOKEN, establecido en el token de acceso personal de Azure Databricks.

Para establecer las variables de entorno, consulte la documentación del sistema operativo.

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

Autenticación de usuario a máquina (U2M) de OAuth

Databricks SQL Driver for Node.js versiones 1.8.0 y posteriores admiten autenticación de usuario a máquina (U2M) de OAuth.

Para autenticar el controlador SQL de Databricks para Node.js con la autenticación U2M de OAuth, use el siguiente fragmento de código. En este fragmento, se da por supuesto que ha establecido las siguientes variables de entorno:

  • DATABRICKS_SERVER_HOSTNAMEestablecido en el valor de Nombre de host del servidor del clúster o almacén de SQL.
  • DATABRICKS_HTTP_PATH, establecido en el valor de Ruta de acceso HTTP del clúster o almacén del SQL.

Para establecer las variables de entorno, consulte la documentación del sistema operativo.

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

Autenticación de máquina a máquina (M2M) de OAuth

Databricks SQL Driver for Node.js versiones 1.8.0 y posteriores admiten autenticación de máquina a máquina (U2M) de OAuth.

Para usar el controlador SQL de Databricks para Node.js con la autenticación de OAuth M2M, debe hacer lo siguiente:

  1. Cree una entidad de servicio de Azure Databricks en el área de trabajo de Azure Databricks y cree un secreto de OAuth para esa entidad de servicio.

    Para crear la entidad de servicio y su secreto de OAuth, consulte Uso de una entidad de servicio para autenticarse con Azure Databricks. Anote los valores de UUID o Id. de la aplicación de la entidad de servicio, así como el valor de Secreto del secreto de OAuth de la entidad de servicio.

  2. Proporcione a la entidad de servicio acceso al clúster o al almacenamiento. Consulte Permisos de proceso o Administración de un almacén de SQL.

Para autenticar el controlador Databricks SQL para Node.js, use el siguiente fragmento de código. En este fragmento, se da por supuesto que ha establecido las siguientes variables de entorno:

  • DATABRICKS_SERVER_HOSTNAMEestablecido en el valor de Nombre de host del servidor del clúster o almacén de SQL.
  • DATABRICKS_HTTP_PATH, establecido en el valor de Ruta de acceso HTTP del clúster o almacén del SQL.
  • DATABRICKS_CLIENT_ID, establecido en el valor del UUID o Id. de aplicación de la entidad de servicio.
  • DATABRICKS_CLIENT_SECRET, establecido en el Secreto del secreto de OAuth de la entidad de servicio.

Para establecer las variables de entorno, consulte la documentación del sistema operativo.

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

Autenticación mediante token de Microsoft Entra ID (anteriormente Azure Active Directory)

Para usar la autenticación de tokens de Databricks SQL Driver para Node.js con el Microsoft Entra ID (anteriormente Azure Active Directory), debe proporcionar el controlador SQL de Databricks para Node.js con el token de Microsoft Entra ID. Para crear un token de acceso de Microsoft Entra ID, haga lo siguiente:

Los tokens de Microsoft Entra ID tienen una duración predeterminada de aproximadamente 1 hora. Para crear un nuevo token de Microsoft Entra ID, repita este proceso.

Para autenticar el controlador Databricks SQL para Node.js, use el siguiente fragmento de código. En este fragmento, se da por supuesto que ha establecido las siguientes variables de entorno:

  • DATABRICKS_SERVER_HOSTNAMEestablecido en el valor de Nombre de host del servidor del clúster o almacén de SQL.
  • DATABRICKS_HTTP_PATH, establecido en el valor de Ruta de acceso HTTP del clúster o almacén del SQL.
  • DATABRICKS_TOKEN, establecido en el token de Microsoft Entra ID.

Para establecer las variables de entorno, consulte la documentación del sistema operativo.

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 datos

En el ejemplo de código siguiente se muestra cómo llamar al Controlador de Databricks SQL para Node.js para ejecutar una consulta SQL básica en un recurso de proceso de Azure Databricks. Este comando devuelve las dos primeras filas de la tabla trips del esquema nyctaxi del catálogo samples.

Nota:

En el ejemplos de código siguiente se muestra cómo usar un token de acceso personal de Azure Databricks para la autenticación. Para usar otros tipos de autenticación disponibles de Azure Databricks, consulte Autenticación.

En este ejemplo de código se recuperan los valores de variable de conexión token, server_hostname y http_path de un conjunto de variables de entorno de Azure Databricks. Estas variables de entorno tienen los siguientes nombres de variable de entorno:

  • DATABRICKS_TOKEN, que representa el token de acceso personal de Azure Databricks de los requisitos.
  • DATABRICKS_SERVER_HOSTNAME, que representa el valor de Nombre de host del servidor de los requisitos.
  • DATABRICKS_HTTP_PATH, que representa el valor de Ruta de acceso HTTP de los requisitos.

Puede usar otros enfoques para recuperar estos valores de variable de conexión. El uso de variables de entorno es solo un enfoque entre muchos.

En el ejemplo de código siguiente, se muestra cómo llamar a Databricks SQL Connector para Node.js para ejecutar un comando SQL básico en un clúster o un almacenamiento SQL. Este comando devuelve las dos primeras filas de la tabla trips.

JavaScript

const { DBSQLClient } = require('@databricks/sql');

const token          = process.env.DATABRICKS_TOKEN;
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath       = process.env.DATABRICKS_HTTP_PATH;

if (!token || !serverHostname || !httpPath) {
  throw new Error("Cannot find Server Hostname, HTTP Path, or personal access token. " +
                  "Check the environment variables DATABRICKS_TOKEN, " +
                  "DATABRICKS_SERVER_HOSTNAME, and DATABRICKS_HTTP_PATH.");
}

const client = new DBSQLClient();
const connectOptions = {
  token: token,
  host: serverHostname,
  path: httpPath
};

client.connect(connectOptions)
  .then(async client => {
    const session = await client.openSession();
    const queryOperation = await session.executeStatement(
      'SELECT * FROM samples.nyctaxi.trips LIMIT 2',
      {
        runAsync: true,
        maxRows:  10000 // This option enables the direct results feature.
      }
    );

    const result = await queryOperation.fetchAll();

    await queryOperation.close();

    console.table(result);

    await session.close();
    await client.close();
})
.catch((error) => {
  console.error(error);
});

TypeScript

import { DBSQLClient } from '@databricks/sql';
import IDBSQLSession from '@databricks/sql/dist/contracts/IDBSQLSession';
import IOperation from '@databricks/sql/dist/contracts/IOperation';

const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string       = process.env.DATABRICKS_HTTP_PATH || '';
const token: string          = process.env.DATABRICKS_TOKEN || '';

if (serverHostname == '' || httpPath == '' || token == '') {
  throw new Error("Cannot find Server Hostname, HTTP Path, or personal access token. " +
                  "Check the environment variables DATABRICKS_SERVER_HOSTNAME, " +
                  "DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.");
}

const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
  host: serverHostname,
  path: httpPath,
  token: token
};

client.connect(connectOptions)
  .then(async client => {
    const session: IDBSQLSession = await client.openSession();

    const queryOperation: IOperation = await session.executeStatement(
      'SELECT * FROM samples.nyctaxi.trips LIMIT 2',
      {
        runAsync: true,
        maxRows: 10000 // This option enables the direct results feature.
      }
    );

    const result = await queryOperation.fetchAll();

    await queryOperation.close();

    console.table(result);

    await session.close();
    client.close();
  })
  .catch((error) => {
    console.error(error);
});

Salida:

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

Sesiones

Todos los métodos IDBSQLSession que devuelven objetos IOperationen la referencia de API tienen los siguientes parámetros comunes que afectan a su comportamiento:

  • Configurando runAsync a true inicia el modo asíncrono. IDBSQLSession métodos colocan las operaciones en la cola y devuelven lo más rápido posible. El estado actual del objeto devuelto IOperation puede variar y el cliente es responsable de comprobar su estado antes de usar el devuelto IOperation. Consulte Operaciones. Configurar runAsync en false significa que los métodos esperan a que IDBSQLSession se completen las operaciones. Databricks recomienda configurar siempre runAsync entrue.
  • Si se establece maxRows en un valor distinto de NULL, se habilitan los resultados directos. Con los resultados directos, el servidor intenta esperar a que se completen las operaciones y a continuación, capture una parte de los datos. Dependiendo de cuánto trabajo pudo completar el servidor dentro del tiempo definido, los objetos IOperation devuelven en algún estado intermedio en lugar de en algún estado pendiente. A menudo, todos los metadatos y los resultados de la consulta se devuelven dentro de una sola solicitud al servidor. El servidor usa maxRows para determinar cuántos registros puede devolver inmediatamente. Sin embargo, el fragmento real puede tener un tamaño diferente; consulte IDBSQLSession.fetchChunk. Los resultados directos están habilitados de manera predeterminada. Databricks recomienda deshabilitar los resultados directos.

Operaciones

Como se describe en Sesiones, IOperation los objetos devueltos por los IDBSQLSession métodos de sesión en la referencia de API no se rellenan completamente. La operación del servidor relacionada podría estar aún en curso, como esperar a que se inicie el almacén SQL de Databricks, ejecutar la consulta o recuperar los datos. La clase IOperation oculta estos detalles de los usuarios. Por ejemplo, los métodos como fetchAll, fetchChunky getSchema esperan internamente para que las operaciones se completen y a continuación, devuelvan resultados. Puede usar el método IOperation.finished() para esperar explícitamente a que se completen las operaciones. Estos métodos toman una devolución de llamada que se llama periódicamente mientras espera a que se completen las operaciones. Establecer la opción progress para true intentar solicitar datos de progreso adicionales desde el servidor y pasarlos a esa devolución de llamada.

Los métodosclose y cancel se pueden llamar en cualquier momento. Cuando se llama, invalidan inmediatamente el objetoIOperation; todas las llamadas pendientes como fetchAll, fetchChunky getSchema, se cancelan inmediatamente y se devuelve un error. En algunos casos, es posible que la operación del servidor ya se haya completado y el método cancel solo afecta al cliente.

El métodofetchAll llama a fetchChunk internamente y recopila todos los datos en una matriz. Aunque esto es conveniente, puede provocar errores de memoria insuficiente cuando se usan en grandes conjuntos de datos. Normalmente, las opciones fetchAll se pasan a fetchChunk.

Capturar fragmentos de datos

La captura de fragmentos de datos usa el siguiente patrón de código:

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

El fetchChunk método de la referencia de API procesa los datos en pequeñas partes para reducir el consumo de memoria. fetchChunk primero espera a que las operaciones se completen si aún no se han completado, llama a una devolución de llamada durante el ciclo de espera y despúes captura el siguiente fragmento de datos.

Puede usar la opción maxRows para especificar el tamaño de fragmento deseado. Sin embargo, el fragmento devuelto puede tener un tamaño diferente, más pequeño o incluso a veces mayor. fetchChunk no intenta capturar previamente los datos internamente, con el fin de segmentarlos en las partes solicitadas. Envía la opción maxRows al servidor y le devuelve lo que el servidor le devuelva. No confunda esta opción maxRows con la de IDBSQLSession. maxRowspasado a fetchChunk define el tamaño de cada fragmento y no hace nada más.

Administrar archivos en volúmenes del catálogo de Unity

El controlador SQL de Databricks permite escribir archivos locales en los Volúmenes del catálogo de Unity, descargar archivos de volúmenes y eliminar archivos de volúmenes, tal y como se muestra en el ejemplo siguiente:

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

registro

El registrador proporciona información para depurar problemas con el conector. Se crean instancias de todos los objetos DBSQLClient con un registrador que se imprime en la consola, pero pasando un registrador personalizado, puede enviar esta información a un archivo. En el ejemplo siguiente se muestra cómo configurar un registrador y cambiar su nivel.

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 obtener más ejemplos, consulte la carpeta examples del repositorio databricks/databricks-sql-nodejs en GitHub.

Prueba

Para probar el código, puede usar marcos de prueba de JavaScript, como Jest. Para probar el código en condiciones simuladas sin llamar a los puntos de conexión de la API de REST de Azure Databricks ni cambiar el estado de las cuentas o áreas de trabajo de Azure Databricks, puede usar marcos de simulacro integrados de Jest’.

Por ejemplo, dado el siguiente archivo denominado helpers.js que contiene una función getDBSQLClientWithPAT que usa un token de acceso personal de Azure Databricks para devolver una conexión a un área de trabajo de Azure Databricks, una función getAllColumnsFromTable que usa la conexión para obtener el número especificado de filas de datos de la tabla especificada (por ejemplo, la tabla trips del esquema samples del catálogo de nyctaxi), y una función printResults para imprimir las filas de datos contenido:

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

Y dado el siguiente archivo denominado main.js que llama a las funciones getDBSQLClientWithPAT, getAllColumnsFromTable, y 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);
  });

El siguiente archivo denominado helpers.test.js comprueba si la función getAllColumnsFromTable devuelve la respuesta esperada. En lugar de crear una conexión real al área de trabajo de destino, esta prueba simula un objeto DBSQLClient. La prueba también simula algunos datos que se ajustan al esquema y los valores que se encuentran en los datos reales. La prueba devuelve los datos ficticios a través de la conexión simulada y, a continuación, comprueba si uno de los valores de filas de datos simulados coincide con el 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);
});

En TypeScript, el código anterior tiene un aspecto similar. Para las pruebas de Jest con TypeScript, use ts-jest.

Recursos adicionales

Referencia de API

Clases

Clase DBSQLClient

Punto de entrada principal para interactuar con una base de datos.

Métodos
Método connect

Abre una conexión a la base de datos.

Parámetros
options

Escriba: ConnectionOptions

Conjunto de opciones usadas para conectarse a la base de datos.

Los campos host, path y otros obligatorios deben rellenarse. Consulte Autenticación.

Ejemplo:


const client: DBSQLClient = new DBSQLClient();

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

Devuelve: Promise<IDBSQLClient>

Método openSession

Abre la sesión entre DBSQLClient y la base de datos.

Parámetros
Solicitud

Escriba: OpenSessionRequest

Conjunto de parámetros opcionales para especificar el esquema y el catálogo iniciales.

Ejemplo:


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

Devuelve: Promise<IDBSQLSession>

Método getClient

Devuelve el objeto TCLIService.Client interno de Thrift. Se debe llamar después de que DBSQLClient se haya conectado.

Sin parámetros

Devuelve TCLIService.Client

Método close

Cierra la conexión a la base de datos y libera todos los recursos asociados en el servidor. Las llamadas adicionales a esta conexión generarán un error.

No hay parámetros.

No devuelve ningún valor.

Clase DBSQLSession

DBSQLSessions se usa principalmente para la ejecución de instrucciones en la base de datos, así como para varias operaciones de captura de metadatos.

Métodos
Método executeStatement

Ejecuta una instrucción con las opciones proporcionadas.

Parámetros
instrucción

Escriba: str

La instrucción que se va a ejecutar.
options

Escriba: ExecuteStatementOptions

Conjunto de parámetros opcionales para determinar el tiempo de espera de la consulta, el número máximo de filas para los resultados directos y si se va a ejecutar la consulta de forma asincrónica. De forma predeterminada, maxRows se estable en 10000. Si maxRows se establece en null, la operación se ejecutará con la característica de resultados directos desactivada.

Ejemplo:


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

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

Devuelve: Promise<IOperation>

Método close

Cierra la sesión. Debe realizarse después de usar la sesión.

No hay parámetros.

No devuelve ningún valor.

Método getId

Devuelve el GUID de la sesión.

No hay parámetros.

Devuelve: str

Método getTypeInfo

Devuelve información sobre los tipos de datos admitidos.

Parámetros
Solicitud

Escriba: TypeInfoRequest

Parámetros de solicitud.

Devuelve: Promise<IOperation>

Método getCatalogs

Obtiene la lista de catálogos.

Parámetros
Solicitud

Escriba: CatalogsRequest

Parámetros de solicitud.

Devuelve: Promise<IOperation>

Método getSchemas

Obtiene la lista de esquemas.

Parámetros
Solicitud

Escriba: SchemasRequest

Parámetros de solicitud. Los campos catalogName y schemaName se pueden usar para el filtrado.

Devuelve: Promise<IOperation>

Método getTables

Obtiene la lista de tablas.

Parámetros
Solicitud

Escriba: TablesRequest

Parámetros de solicitud. Los campos catalogName, schemaName y
tableName se pueden usar para el filtrado.

Devuelve: Promise<IOperation>

Método getFunctions

Obtiene la lista de tablas.

Parámetros
Solicitud

Escriba: FunctionsRequest

Parámetros de solicitud. El campo functionName es obligatorio.

Devuelve: Promise<IOperation>

Método getPrimaryKeys

Obtiene la lista de claves principales.

Parámetros
Solicitud

Escriba: PrimaryKeysRequest

Parámetros de solicitud. Los campos schemaName y tableName son obligatorios.

Devuelve: Promise<IOperation>

Método getCrossReference

Obtiene información sobre las claves externas entre dos tablas.

Parámetros
Solicitud

Escriba: CrossReferenceRequest

Parámetros de solicitud. El esquema, el elemento principal y el nombre del catálogo deben especificarse para ambas tablas.

Devuelve: Promise<IOperation>

Clase DBSQLOperation

DBSQLOperations se crea mediante DBSQLSessions y se puede usar para capturar los resultados de las instrucciones y comprobar su ejecución. Los datos se capturan a través de las funciones fetchChunk y fetchAll.

Métodos
Método getId

Devuelve el GUID de la operación.

No hay parámetros.

Devuelve: str

Método fetchAll

Espera a que finalice la operación y, luego, captura todas las filas de la operación.

Parámetros: None

Devuelve: Promise<Array<object>>

Método fetchChunk

Espera a que finalice la operación y, luego, captura hasta un número especificado de filas de una operación.

Parámetros
options

Escriba: FetchOptions

Opciones usadas para la captura. Actualmente, la única opción es maxRows, que corresponde al número máximo de objetos de datos que se van a devolver en cualquier matriz determinada.

Devuelve: Promise<Array<object>>

Método close

Cierra la operación y libera todos los recursos asociados. Debe realizarse después de dejar de usar la operación.

No hay parámetros.

No devuelve ningún valor.