適用於 Node.js 的 Databricks SQL 驅動程式是一個 Node.js 程式庫,可讓您使用 JavaScript 程式碼,在 Azure Databricks 計算資源上執行 SQL 命令。
需求
執行 Node.js 版本 14 或更高版本的開發機器。 若要列印所安裝的 Node.js 版本,請執行
node -v命令。 若要安裝和使用不同版本的 Node.js,您可以使用節點版本管理員 (nvm) 之類的工具。節點套件管理員 (
npm)。 更新版本的 Node.js 已包含npm。 若要檢查是否已安裝npm,請執行命令npm -v。 若要視需要安裝npm,您可以遵循指示,例如下載並安裝 npm 中的指示。@databricks/sql 套件來自npm。 若要在 Node.js 專案中將
@databricks/sql套件安裝為相依性,請使用npm在專案的相同目錄中執行下列指令:npm i @databricks/sql若要在 Node.js 專案中安裝和使用 TypeScript 以便用作
devDependencies,請使用npm在專案目錄中執行下列指令:npm i -D typescript npm i -D @types/node現有叢集或 SQL 倉儲的伺服器主機名稱和 HTTP 路徑值。
驗證
適用於 Node.js 的 Databricks SQL 驅動程式支援下列 Azure Databricks 驗證類型:
適用於 Node.js 的 Databricks SQL 驅動程式尚不支援下列 Azure Databricks 驗證類型:
注意
基於安全性最佳做法,您不應該將連線變數值硬式編碼到您的程式碼中。 相反地,您應從安全的位置擷取這些連線變數值。 例如,本文中的程式碼片段和範例會使用環境變數。
Databricks 個人存取憑證驗證
若要搭配驗證使用 Databricks SQL Driver for Node.js,您必須先建立 Azure Databricks 個人存取令牌。 如需此步驟的詳細資訊,請參閱為 工作區使用者建立個人存取權杖。
若要驗證適用於 Node.js 的 Databricks SQL 驅動程式,請使用下列程式碼片段。 此片段假設您已設定下列環境變數:
- 將
DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的 [伺服器主機名稱] 值。 -
DATABRICKS_HTTP_PATH設定為您的叢集或 SQL 倉儲的 HTTP 路徑 值。 -
DATABRICKS_TOKEN,設定為 Azure Databricks 個人存取權限憑證。
若要設定環境變數,請參閱作業系統的文件。
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const serverHostname = process.env.DATABRICKS_SERVER_HOSTNAME;
const httpPath = process.env.DATABRICKS_HTTP_PATH;
const token = process.env.DATABRICKS_TOKEN;
if (!token || !serverHostname || !httpPath) {
throw new Error(
'Cannot find Server Hostname, HTTP Path, or ' +
'personal access token. ' +
'Check the environment variables DATABRICKS_SERVER_HOSTNAME, ' +
'DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.',
);
}
const client = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath,
};
client.connect(connectOptions);
// ...
TypeScript
import { DBSQLClient } from '@databricks/sql';
const serverHostname: string = process.env.DATABRICKS_SERVER_HOSTNAME || '';
const httpPath: string = process.env.DATABRICKS_HTTP_PATH || '';
const token: string = process.env.DATABRICKS_TOKEN || '';
if (token == '' || serverHostname == '' || httpPath == '') {
throw new Error(
'Cannot find Server Hostname, HTTP Path, or personal access token. ' +
'Check the environment variables DATABRICKS_SERVER_HOSTNAME, ' +
'DATABRICKS_HTTP_PATH, and DATABRICKS_TOKEN.',
);
}
const client: DBSQLClient = new DBSQLClient();
const connectOptions = {
token: token,
host: serverHostname,
path: httpPath,
};
client.connect(connectOptions);
// ...
OAuth 用戶對機器 (U2M) 驗證
適用於 Node.js 的 Databricks SQL 驅動程式 1.8.0 版和更新版本支援 OAuth 使用者對機器 (U2M) 驗證。
若要使用 OAuth U2M 驗證來驗證適用於 Node.js 的 Databricks SQL 驅動程式,請使用下列程式碼片段。 此片段假設您已設定下列環境變數:
- 將
DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的 [伺服器主機名稱] 值。 -
DATABRICKS_HTTP_PATH設定為您的叢集或 SQL 倉儲的 HTTP 路徑 值。
若要設定環境變數,請參閱作業系統的文件。
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',
azureTenantId: '<tenant-id>',
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',
azureTenantId: '<tenant-id>',
useDatabricksOAuthInAzure: true,
host: serverHostname,
path: httpPath,
};
client.connect(connectOptions);
// ...
OAuth 機器對機器 (M2M) 驗證
適用於 Node.js 的 Databricks SQL 驅動程式 1.8.0 版和更新版本支援 OAuth 機器對機器 (U2M) 驗證。
若要使用 OAuth M2M 驗證來驗證適用於 Node.js 的 Databricks SQL 驅動程式,您必須執行下列動作:
在 Azure Databricks 工作區中建立 Azure Databricks 服務主體,並為該服務主體建立 OAuth 祕密。
若要建立服務主體及其 OAuth 秘密,請參閱 使用 OAuth 授權服務主體存取 Azure Databricks。 記下服務主體的 UUID 或 應用程式識別碼 值,以及服務主體的 OAuth 秘密值。
若要驗證適用於 Node.js 的 Databricks SQL 驅動程式,請使用下列程式碼片段。 此片段假設您已設定下列環境變數:
- 將
DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的 [伺服器主機名稱] 值。 -
DATABRICKS_HTTP_PATH設定為您的叢集或 SQL 倉儲的 HTTP 路徑 值。 -
DATABRICKS_CLIENT_ID,設定為服務主體的 UUID 或 應用程式識別碼 值。 -
DATABRICKS_CLIENT_SECRET,設定服務主體的 OAuth 憑證為 Secret 值。
若要設定環境變數,請參閱作業系統的文件。
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',
azureTenantId: '<tenant-id>',
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',
azureTenantId: '<tenant-id>',
useDatabricksOAuthInAzure: true,
host: serverHostname,
path: httpPath,
oauthClientId: clientId,
oauthClientSecret: clientSecret,
};
client.connect(connectOptions);
// ...
Microsoft Entra ID 令牌驗證
若要使用適用於 Node.js 的 Databricks SQL 驅動程式搭配 Microsoft Entra ID 權杖驗證,您必須提供適用於 Node.js 的 Databricks SQL 驅動程式和 Microsoft Entra ID 權杖。 若要建立 Microsoft Entra ID 存取權杖,請按照下列步驟操作:
- 針對 Azure Databricks 使用者,您可使用 Azure CLI。 請參閱 手動取得 Microsoft Entra ID 令牌。
- 如需 Microsoft Entra ID 服務主體的相關資訊,請參閱 取得服務主體的權杖。 若要建立Microsoft Entra ID 受控服務主體,請參閱 服務主體。
Microsoft Entra ID 權杖的預設有效期間約為 1 小時。 若要建立新的 Microsoft Entra ID 權杖,請重複此程序。
若要驗證適用於 Node.js 的 Databricks SQL 驅動程式,請使用下列程式碼片段。 此片段假設您已設定下列環境變數:
- 將
DATABRICKS_SERVER_HOSTNAME設定為叢集或 SQL 倉儲的 [伺服器主機名稱] 值。 -
DATABRICKS_HTTP_PATH設定為您的叢集或 SQL 倉儲的 HTTP 路徑 值。 -
DATABRICKS_TOKEN,設定為 Microsoft Entra ID 代幣。
若要設定環境變數,請參閱作業系統的文件。
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);
// ...
設定 User-Agent
下列程式代碼範例示範如何設定 User-Agent 應用程式 product_name 以進行使用追蹤。
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const client = new DBSQLClient();
client.connect({
host: process.env.DATABRICKS_SERVER_HOSTNAME,
path: process.env.DATABRICKS_HTTP_PATH,
token: process.env.DATABRICKS_TOKEN,
userAgentEntry: 'product_name',
});
查詢資料
下列程式碼範例示範如何呼叫適用於 Node.js 的 Databricks SQL 驅動程式,在 Azure Databricks 計算資源上執行基本 SQL 查詢。 此命令會從trips目錄的samples架構中傳回nyctaxi數據表的前兩列。
注意
下列程式碼範例示範如何使用 Azure Databricks 個人存取權杖進行驗證。 若要改用其他可用的 Azure Databricks 驗證類型,請參閱驗證。
此程式碼範例會從一組 Azure Databricks 環境變數擷取 token、server_hostname 和 http_path 連線變數值。 這些環境變數具有下列環境變數名稱:
-
DATABRICKS_TOKEN,代表需求中指定的 Azure Databricks 個人存取權杖。 -
DATABRICKS_SERVER_HOSTNAME,代表來自需求的 [伺服器主機名稱] 值。 -
DATABRICKS_HTTP_PATH,代表來自需求的 [HTTP 路徑] 值。
您可使用其他方法來擷取這些連線變數值。 使用環境變數只是眾多方法之一。
下列程式碼範例示範如何呼叫適用於 Node.js 的 Databricks SQL 驅動程式,在叢集或 SQL 倉儲上執行基本 SQL 命令。 此命令會從 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 ?', {
runAsync: true,
maxRows: 10000, // This option enables the direct results feature.
ordinalParameters: [2],
});
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 ?', {
runAsync: true,
maxRows: 10000, // This option enables the direct results feature.
ordinalParameters: [2],
});
const result = await queryOperation.fetchAll();
await queryOperation.close();
console.table(result);
await session.close();
client.close();
})
.catch((error) => {
console.error(error);
});
查詢標籤範例
這很重要
這項功能處於個人預覽版狀態。 若要要求存取權,請聯絡您的客戶團隊。
查詢標籤是鍵值對,可以附加到 SQL 查詢以用於追蹤和分析目的。 設定後,它們會出現在表格中 system.query.history ,可讓您分析查詢模式和使用情況。
將查詢標籤定義為逗號分隔的索引鍵值組,其中每個索引鍵和值都以冒號分隔,例如 key1:value1,key2:value2。
下列範例示範如何搭配工作階段組態使用查詢標籤:
JavaScript
const { DBSQLClient } = require('@databricks/sql');
const client = new DBSQLClient();
// Open session with query tags configuration
const session = await client.openSession({
configuration: {
query_tags: 'team:engineering,test:query-tags,driver:node',
},
});
const queryOperation = await session.executeStatement('SELECT 1');
const result = await queryOperation.fetchAll();
console.log(result);
await queryOperation.close();
await session.close();
TypeScript
import { DBSQLClient } from '@databricks/sql';
const client: DBSQLClient = new DBSQLClient();
// Open session with query tags configuration
const session = await client.openSession({
configuration: {
query_tags: 'team:engineering,test:query-tags,driver:node',
},
});
const queryOperation = await session.executeStatement('SELECT 1');
const result = await queryOperation.fetchAll();
console.log(result);
await queryOperation.close();
await session.close();
會議
在 IDBSQLSession 中,所有返回 IOperation 物件的 方法都有以下會影響其行為的常見參數:
- 將
runAsync設定為true啟動異步模式。IDBSQLSession方法會將作業放入佇列中,並儘快傳回。 傳回IOperation物件的目前狀態可能會有所不同,而且用戶端會負責檢查其狀態,再使用傳回的IOperation。 請參閱作業。 將runAsync設定為false,表示IDBSQLSession方法會等候作業完成。 Databricks 建議一律將runAsync設定為true。 - 將
maxRows設定為非 Null 值會啟用直接結果。 透過直接結果,伺服器會嘗試等候作業完成,然後擷取部分資料。 根據伺服器能夠在定義的時間內完成多少工作,IOperation物件會以某些中繼狀態傳回,而不是在某些擱置狀態中傳回。 所有中繼資料和查詢結果通常會在單一要求內傳回給伺服器。 伺服器會使用maxRows來判斷可以立即傳回的記錄數量。 不過,實際區塊的大小可能不同;請參閱IDBSQLSession.fetchChunk。 預設狀態會啟用直接結果功能。 Databricks 建議禁止停用直接結果。
會話設定
您可以在configuration方法中使用openSession物件,開啟工作階段時傳遞工作階段配置參數。 這些參數會影響該工作階段內所有作業的行為。
常見的工作階段配置參數包括:
-
query_tags:將鍵值標籤附加至 SQL 查詢以進行追蹤和分析。 如需詳細資訊,請參閱 查詢標籤範例。 -
ansi_mode:控制 ANSI SQL 合規性模式 ('true'或'false') -
timezone:設定工作階段時區(例如,'UTC','America/New_York')
營運
如工作階段中所述,IOperation中的 IDBSQLSession 工作階段方法所傳回的物件不會完全填滿。 相關的伺服器作業可能仍在進行中,例如等候 Databricks SQL 倉儲啟動、執行查詢或擷取資料。
IOperation 類別會向使用者隱藏這些詳細資料。 例如,fetchAll、fetchChunk 和 getSchema 等方法會在內部等候作業完成,然後傳回結果。 您可使用 IOperation.finished() 方法來明確等候作業完成。 這些方法會接受一個在等待作業完成時定期被呼叫的回呼函數。 設定 progress 選項為 true,以嘗試向伺服器要求額外的進度資料,並將其傳遞至該回呼。
可以隨時呼叫 close 和 cancel 方法。 呼叫時,它們會立即使 IOperation 物件失效;所有擱置的呼叫,例如 fetchAll、fetchChunk 和 getSchema 都會立即取消,並傳回錯誤。 在某些情況下,伺服器作業可能已經完成,並且 cancel 方法只會影響用戶端。
fetchAll 方法會在內部呼叫 fetchChunk,並將所有資料收集到陣列中。 雖然這樣做很方便,但在對大型資料集進行操作時,可能會造成記憶體不足錯誤。
fetchAll 選項通常會傳遞至 fetchChunk。
擷取資料區塊
擷取資料區塊會使用下列程式碼模式:
do {
const chunk = await operation.fetchChunk();
// Process the data chunk.
} while (await operation.hasMoreRows());
fetchChunk 方法在 API 參考 中會處理小部分的資料,以減少記憶體使用量。 如果作業尚未完成,fetchChunk 先等候作業完成,然後在等候週期內呼叫回呼,然後擷取下一個資料區塊。
您可以使用 maxRows 選項來指定所需區塊大小。 不過,傳回的區塊可能會有不同的大小,較小,有時甚至更大。
fetchChunk 不會嘗試在內部預先擷取資料來將其分割成所需的部分。 它會將 maxRows 選項傳送至伺服器,並傳回伺服器所傳回的內容。 請勿將此 maxRows 選項與 IDBSQLSession 中的選項混淆。 傳遞至 maxRows 的 fetchChunk 定義每個區塊的大小,且不會執行任何其他動作。
管理 Unity 目錄磁碟區中的檔案
Databricks SQL 驅動程式可讓您將本機檔案寫入 Unity 目錄磁碟區、從磁碟區下載檔案,以及從磁碟區刪除檔案,如下列範例所示:
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);
});
配置日誌記錄
記錄器會提供連接器問題偵錯的資訊。 所有 DBSQLClient 物件在實例化時都會附帶一個記錄器,將資訊輸出到主控台,但您可以使用自訂記錄器,將此資訊傳送到檔案。 下列範例示範如何設定記錄器並變更其層級。
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);
如需其他範例,請參閱 GitHub 上 databricks/databricks-sql-nodejs 存放庫中的範例資料夾。
測試
若要測試程式碼,您可以使用 JavaScript 測試架構,例如 Jest。 若要在模擬條件下測試程序代碼,而不呼叫 Azure Databricks REST API 端點,或變更 Azure Databricks 帳戶或工作區的狀態,您可以使用 Jest 的內建模擬架構。
例如,假設下列名為 helpers.js 的檔案,其中包含使用 getDBSQLClientWithPAT Azure Databricks 個人存取令牌傳回 Azure Databricks 工作區連線的函式、getAllColumnsFromTable使用連線從指定數據表取得指定數據列數目的函式(例如trips目錄架構中的samplesnyctaxi數據表),以及printResults列印數據列內容的函式:
// 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();
// Note: Table names cannot be parameterized; validate tableSpec against allowed values
queryOperation = await session.executeStatement(`SELECT * FROM ${tableSpec} LIMIT ?`, {
runAsync: true,
maxRows: 10000, // This option enables the direct results feature.
ordinalParameters: [rowCount],
});
} 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,
};
並假設下列名為 main.js 的檔案,該檔案會呼叫 getDBSQLClientWithPAT、getAllColumnsFromTable 和 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);
});
下列名為 helpers.test.js 的檔案會測試函 getAllColumnsFromTable 式是否傳回預期的回應。 此測試會模擬 DBSQLClient 物件,而不是建立與目標工作區的實際連線。 測試也會模擬一些符合實際資料中結構描述和值的資料。 測試會透過模擬連接傳回仿真的數據,然後檢查其中一個仿真的數據列值是否符合預期的值。
// helpers.test.js
const { getDBSQLClientWithPAT, getAllColumnsFromTable, printResult } = require('./helpers');
jest.mock('@databricks/sql', () => {
return {
DBSQLClient: jest.fn(() => {
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);
});
針對 TypeScript,上述程式碼看起來很類似。 針對使用 TypeScript 的 Jest 測試,使用 ts-jest。
其他資源
- GitHub 上適用於 Node.js 的 Databricks SQL 驅動程式存放庫
- 開始使用適用於 Node.js 的 Databricks SQL 驅動程式
- 針對適用於 Node.js 的 Databricks SQL 驅動程式進行疑難排解
API 文件參考
課程
DBSQLClient 類別
與資料庫互動的主要進入點。
方法
connect 方法
開啟資料庫的連線。
| 參數 |
|---|
|
選項 類型: ConnectionOptions (英文)用來連線到資料庫的一組選項。 必須填入 host、path 和其他必要欄位。 請參閱驗證。欄位 userAgentEntry 可讓您提供 User-Agent,並包含在 HTTP 要求標頭中以進行使用追蹤。 請參閱 設定使用者代理程式。 |
傳回:Promise<IDBSQLClient>
openSession 方法
開啟 DBSQLClient 與資料庫之間的會話。
| 參數 |
|---|
|
請求 類型: OpenSessionRequest (英文)指定初始結構描述和初始目錄的一組選擇性參數 範例: const session = await client.openSession({ initialCatalog: 'catalog' }); |
傳回:Promise<IDBSQLSession>
getClient 方法
傳回內部的 thrift TCLIService.Client 物件。 必須在 DBSQLClient 連線之後呼叫。
無參數
傳回 TCLIService.Client。
close 方法
關閉資料庫的連線,並釋放伺服器上的所有相關聯資源。 此用戶端的任何其他呼叫都會引發錯誤。
無參數。
沒有傳回值。
DBSQLSession 類別
DBSQLSessions 主要用於對資料庫執行陳述式,以及進行各種中繼資料擷取作業。
方法
executeStatement 方法
使用所提供的選項執行陳述式。
| 參數 |
|---|
|
聲明 類型: str (英文)要執行的語句。 選項 類型: ExecuteStatementOptions (英文)一組選擇性參數,用於判斷查詢逾時、直接結果的資料列上限,以及是否要以異步方式執行查詢。 預設會將 maxRows 設定為 10000。 如果將 maxRows 設定為 null,作業將會在關閉直接結果功能的情況下執行。範例: const session = await client.openSession({ initialCatalog: 'catalog' });`` queryOperation = await session.executeStatement('SELECT "Hello, World!"', { runAsync: true }); |
傳回:Promise<IOperation>
close 方法
關閉工作階段。 必須在工作階段結束後完成。
無參數。
沒有傳回值。
getId 方法
傳回工作階段的 GUID。
無參數。
傳回:str
getTypeInfo 方法
傳回支援的資料類型的相關資訊。
| 參數 |
|---|
|
請求 類型: TypeInfoRequest (英文)請求參數。 |
傳回:Promise<IOperation>
getCatalogs 方法
獲取目錄列表。
| 參數 |
|---|
|
請求 類型: CatalogsRequest (英文)請求參數。 |
傳回:Promise<IOperation>
getSchemas 方法
取得模式的清單。
| 參數 |
|---|
|
請求 類型: SchemasRequest (英文)請求參數。 欄位 catalogName 和 schemaName 可用於篩選目的。 |
傳回:Promise<IOperation>
getTables 方法
取得資料表清單。
| 參數 |
|---|
|
請求 類型: TablesRequest (英文)請求參數。 可用來篩選的欄位為 catalogName、schemaName 和 tableName。 |
傳回:Promise<IOperation>
getFunctions 方法
取得資料表清單。
| 參數 |
|---|
|
請求 類型: FunctionsRequest (英文)請求參數。 欄位 functionName 必填。 |
傳回:Promise<IOperation>
getPrimaryKeys 方法
取得主鍵的清單。
| 參數 |
|---|
|
請求 類型: PrimaryKeysRequest (英文)請求參數。 欄位 schemaName 和 tableName 為必填項。 |
傳回:Promise<IOperation>
getCrossReference 方法
取得兩個資料表之間外來鍵的相關資訊。
| 參數 |
|---|
|
請求 類型: CrossReferenceRequest (英文)請求參數。 兩個資料表都必須指定結構描述、父系和目錄名稱。 |
傳回:Promise<IOperation>
DBSQLOperation 類別
DBSQLOperations 由 DBSQLSessions 所建立,可用來擷取陳述式的結果,並檢查其執行。 資料透過函式 fetchChunk 和 fetchAll 來擷取。
方法
getId 方法
傳回作業的 GUID。
無參數。
傳回:str
fetchAll 方法
等候作業完成,然後從作業擷取所有資料列。
參數:無
傳回:Promise<Array<object>>
fetchChunk 方法
等候作業完成後,最多擷取指定數目的資料列。
| 參數 |
|---|
|
選項 類型: FetchOptions (英文)用來擷取的選項。 目前,唯一的選項是 maxRows,其對應於任何指定陣列中要傳回的資料物件數目上限。 |
傳回:Promise<Array<object>>
close 方法
關閉作業,並釋放所有相關聯的資源。 必須在停止操作後完成。
無參數。
沒有傳回值。