Important
Lakebase 自動スケールは、ベータ版としてeastus2、westeurope、westusの各リージョンで利用できます。
Lakebase 自動スケーリングは、自動スケール コンピューティング、ゼロへのスケーリング、分岐、インスタント リストアを備えた最新バージョンの Lakebase です。 Lakebase Provisioned との機能の比較については、バージョンの選択を参照してください。
このガイドでは、REST API の直接呼び出しを使用して外部アプリケーションを Lakebase 自動スケーリングに接続する方法について説明します。 この方法は、Databricks SDK が言語 (Node.js、Ruby、PHP、Elixir、Rust など) で使用できない場合に使用します。
言語に SDK のサポート (Python、Java、Go) がある場合は、SDK を 使用して外部アプリを Lakebase に接続して 、より簡単なトークン管理を行います。
OAuth トークンローテーションを使用してデータベース資格情報を取得するには、2 つの API 呼び出しを行います。 curl と Node.jsの例を示します。
注
2 段階認証: この方法では、データベース資格情報ごとに 2 つの API 呼び出しが必要です。(1) ワークスペース OAuth トークンのサービス プリンシパル シークレットを交換し、(2) OAuth トークンをデータベース資格情報と交換します。 どちらのトークンも 60 分後に有効期限が切れます。 SDK は手順 1 を自動的に処理します。
[前提条件]
SDK アプローチと同じセットアップが必要です。サービス プリンシパル、Postgres ロール、接続の詳細です。
| 前提条件 | 重要な詳細 | 詳細情報 |
|---|---|---|
| サービス プリンシパル | 最大有効期間が 730 日の OAuth シークレット。ワークスペース アクセスを有効にします。 Postgres ロールと env vars の クライアント ID (UUID) をメモします。 | サービス プリンシパルを作成する |
| Postgres ロール | Lakebase SQL エディターで OAuth ロールを作成し、<c0 /> に CONNECT、USAGE、<c1 />/<c2 />/DELETE の権限を付与します。 手順 1 のクライアント ID を使用します。 | Postgres ロールを作成する |
| 接続の詳細 | Lakebase Console Connect から: エンドポイント名 (projects/.../branches/.../endpoints/...)、 ホスト、 データベース (通常は databricks_postgres)。 |
接続の詳細を取得する |
動作方法
手動 API アプローチには、次の 2 つのトークン交換が必要です。
トークンの有効期間:
- サービス プリンシパル シークレット: 最大 730 日 (作成時に設定)
- ワークスペース OAuth トークン: 60 分 (手順 1)
- データベース資格情報: 60 分 (手順 2)
トークンスコープ: データベース資格情報はワークスペースの範囲内です。
endpoint パラメーターが必要ですが、返されたトークンは、サービス プリンシパルにアクセス許可があるワークスペース内の任意のデータベースまたはプロジェクトにアクセスできます。
環境変数を設定する
アプリケーションを実行する前に、次の環境変数を設定します。
# Databricks workspace authentication
export DATABRICKS_HOST="https://your-workspace.databricks.com"
export DATABRICKS_CLIENT_ID="<service-principal-client-id>"
export DATABRICKS_CLIENT_SECRET="<your-oauth-secret>"
# Lakebase connection details (from prerequisites)
export ENDPOINT_NAME="projects/<project-id>/branches/<branch-id>/endpoints/<endpoint-id>"
export PGHOST="<endpoint-id>.database.<region>.databricks.com"
export PGDATABASE="databricks_postgres"
export PGUSER="<service-principal-client-id>" # Same UUID as client ID
export PGPORT="5432"
接続コードを追加する
curl
この例では、生の API 呼び出しを示します。 運用アプリケーションの場合は、トークン キャッシュと更新ロジックを実装します。
# Step 1: Get workspace OAuth token
OAUTH_TOKEN=$(curl -s -X POST "${DATABRICKS_HOST}/oidc/v1/token" \
-u "${DATABRICKS_CLIENT_ID}:${DATABRICKS_CLIENT_SECRET}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&scope=all-apis" \
| jq -r '.access_token')
echo "Got workspace OAuth token (60-min lifetime)"
# Step 2: Get database credential
PG_TOKEN=$(curl -s -X POST "${DATABRICKS_HOST}/api/2.0/postgres/credentials" \
-H "Authorization: Bearer ${OAUTH_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"endpoint\": \"${ENDPOINT_NAME}\"}" \
| jq -r '.token')
echo "Got database credential (60-min lifetime)"
# Step 3: Connect to Postgres
PGPASSWORD="${PG_TOKEN}" psql \
-h "${PGHOST}" \
-p "${PGPORT}" \
-U "${PGUSER}" \
-d "${PGDATABASE}" \
-c "SELECT current_user, current_database()"
Node.js
この例では、トークンのフェッチとキャッシュを処理する非同期パスワード関数で node-postgres を使用します。
import pg from 'pg';
// Step 1: Fetch workspace OAuth token
async function getWorkspaceToken(host, clientId, clientSecret) {
const auth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
const response = await fetch(`${host}/oidc/v1/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${auth}`,
},
body: 'grant_type=client_credentials&scope=all-apis',
});
if (!response.ok) {
throw new Error(`OAuth failed: ${response.status}`);
}
const data = await response.json();
return {
token: data.access_token,
expires: Date.now() + data.expires_in * 1000,
};
}
// Step 2: Fetch database credential
async function getPostgresCredential(host, workspaceToken, endpoint) {
const response = await fetch(`${host}/api/2.0/postgres/credentials`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${workspaceToken}`,
},
body: JSON.stringify({ endpoint }),
});
if (!response.ok) {
throw new Error(`Database credential failed: ${response.status}`);
}
const data = await response.json();
return {
token: data.token,
expires: new Date(data.expire_time).getTime(),
};
}
// Simple caching wrapper (production: use more sophisticated caching)
function cached(fetchFn) {
let cache = null;
return async (...args) => {
const now = Date.now();
if (!cache || now >= cache.expires - 5 * 60 * 1000) {
// Refresh 5 min early
const result = await fetchFn(...args);
cache = result;
}
return cache.token;
};
}
// Create connection pool with async password function
function createPool() {
const host = process.env.DATABRICKS_HOST;
const clientId = process.env.DATABRICKS_CLIENT_ID;
const clientSecret = process.env.DATABRICKS_CLIENT_SECRET;
const endpoint = process.env.ENDPOINT_NAME;
const cachedWorkspaceToken = cached(() => getWorkspaceToken(host, clientId, clientSecret));
const cachedPostgresToken = cached(async () => {
const workspaceToken = await cachedWorkspaceToken();
return getPostgresCredential(host, workspaceToken, endpoint);
});
return new pg.Pool({
host: process.env.PGHOST,
port: process.env.PGPORT,
database: process.env.PGDATABASE,
user: process.env.PGUSER,
password: cachedPostgresToken, // Async function: () => Promise<string>
ssl: { rejectUnauthorized: true },
min: 1,
max: 10,
idleTimeoutMillis: 900000, // Example: 15 minutes
connectionTimeoutMillis: 60000, // Example: 60 seconds
});
}
// Use the pool
const pool = createPool();
const result = await pool.query('SELECT current_user, current_database()');
console.log('Connected as:', result.rows[0].current_user);
依存関係:pg (node-postgres)
メモ: Node-postgres (pg) は、非同期関数をパスワードとして受け入れます。 この関数は、新しい接続が作成されるたびに呼び出され、新しいトークンが確保されます。
接続を実行して確認する
curl
環境変数が読み込まれた bash スクリプトを実行します。
export $(cat .env | xargs)
bash connect.sh
想定される出力:
Got workspace OAuth token (60-min lifetime)
Got database credential (60-min lifetime)
current_user | current_database
-----------------------+------------------
c00f575e-d706-4f6b... | databricks_postgres
current_userがサービス プリンシパル クライアント ID と一致する場合、OAuth は正常に動作しています。
Node.js
依存関係をインストールします。
npm install pg
実行:
node app.js
想定される出力:
Connected as: c00f575e-d706-4f6b-b62c-e7a14850571b
メモ: Lakebase Autoscaling が 0 からコンピューティングを開始すると、アイドル後の最初の接続に時間がかかる場合があります。
トラブルシューティング
| エラー | 修正 |
|---|---|
| "invalid_client" または "クライアント認証がありません" |
DATABRICKS_CLIENT_IDとDATABRICKS_CLIENT_SECRETが正しいことを確認します。 基本認証 (base64 エンコード) を使用します。 |
| "ワークスペース アクセス権を持たないユーザーに対して API が無効になっています" | サービス プリンシパルの "ワークスペース アクセス" を有効にします (前提条件)。 |
| "パラメーター値が無効です" / "「endpoint」フィールドが必要です" | ステップ2のPOST本文にendpoint形式のパラメーターがprojects/<id>/branches/<id>/endpoints/<id>必ず含まれていることを確認してください。 |
| "ロールが存在しない" か、認証が失敗する | SQL を使用して OAuth ロールを作成する (前提条件)。 |
| "接続が拒否されました" またはタイムアウト | 0 へのスケール後の最初の接続には、より長い時間がかかる場合があります。 再試行ロジックを実装します。 |
| トークンの有効期限が切れた/ "パスワード認証に失敗しました" | ワークスペース トークンとデータベース トークンの両方が 60 分後に期限切れになります。 有効期限チェックを使用してキャッシュを実装します。 |