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 incluyennpm
. Para comprobar sinpm
está instalado, ejecute el comandonpm -v
. Para instalarnpm
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, usenpm
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
, usenpm
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:
- Autenticación de token de acceso personal de Databricks
- Autenticación de token de Microsoft Entra ID
- autenticación de máquina a máquina (M2M) de OAuth
- Autenticación de usuario a máquina (U2M) de OAuth
Databricks SQL Driver for Node.js aún no admite los siguientes tipos de autenticación de Azure Databricks:
- Autenticación de identidades administradas de Azure
- Autenticación de la entidad de servicio de MS Entra
- Autenticación de la CLI de Azure
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 databricks SQL Driver for Node.js con autenticación, primero debe crear un token de acceso personal de Azure Databricks. Para más información sobre este paso, consulte Tokens de acceso personal de Azure Databricks para los usuarios del área de trabajo.
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_HOSTNAME
establecido 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_HOSTNAME
establecido 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:
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 Autenticación del acceso a Azure Databricks con una entidad de servicio mediante OAuth (OAuth M2M). 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.
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_HOSTNAME
establecido 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 de token de Microsoft Entra ID
Para usar el controlador Databricks SQL para Node.js con la autenticación de token de Microsoft Entra ID, debe proporcionar el controlador Databricks SQL para Node.js con el token de Microsoft Entra ID. Para crear un token de acceso de Microsoft Entra ID, haga lo siguiente:
- Para un usuario de Azure Databricks, puede usar la CLI de Azure. Consulte Obtención de tokens de Microsoft Entra ID para usuarios mediante la CLI de Azure.
- Para obtener una entidad de servicio de Microsoft Entra ID, consulte Obtener un token de acceso de Microsoft Entra ID con la CLI de Azure. Para crear una entidad de servicio administrada de Microsoft Entra ID, vea Administrar entidades de servicio.
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_HOSTNAME
establecido 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 IOperation
en la referencia de API tienen los siguientes parámetros comunes que afectan a su comportamiento:
- Configurando
runAsync
atrue
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 devueltoIOperation
puede variar y el cliente es responsable de comprobar su estado antes de usar el devueltoIOperation
. Consulte Operaciones. ConfigurarrunAsync
enfalse
significa que los métodos esperan a queIDBSQLSession
se completen las operaciones. Databricks recomienda configurar siemprerunAsync
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 objetosIOperation
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 usamaxRows
para determinar cuántos registros puede devolver inmediatamente. Sin embargo, el fragmento real puede tener un tamaño diferente; consulteIDBSQLSession.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
, fetchChunk
y 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
, fetchChunk
y 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
. maxRows
pasado 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
- El repositorio del Controlador de Databricks SQL para Node.js en GitHub
- Introducción al Controlador de Databricks SQL para Node.js
- Solución de problemas del Controlador de Databricks SQL para Node.js
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 ytableName 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.