Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве показано, как подключить внешние приложения к Автомасштабированию Lakebase с помощью прямых вызовов REST API. Используйте этот подход, если пакет SDK Databricks недоступен для вашего языка (Node.js, Ruby, PHP, Elixir, Rust и т. д.).
Если язык поддерживает пакет SDK (Python, Java или Go), используйте подключение внешнего приложения к Lakebase с помощью пакета SDK для более простого управления маркерами.
Вы выполняете два вызова API для получения учетных данных базы данных с помощью смены маркера OAuth. Примеры приведены для curl и Node.js.
Замечание
Двухэтапная аутентификация: Этот подход требует двух вызовов API для каждой учетной записи базы данных: (1) обменять секрет учетной записи служебного принципала на токен OAuth рабочей области; (2) обменять токен OAuth на учетные данные базы данных. Срок действия обоих токенов истекает через 60 минут. Пакет SDK автоматически обрабатывает шаг 1.
Предпосылки
Вам нужна та же настройка, что и подход пакета SDK: субъект-служба, роль Postgres и сведения о подключении.
| Предпосылка | Основные сведения | Дополнительная информация |
|---|---|---|
| Управляющий службой | Секрет OAuth с 730-дневным максимальным временем существования; включите доступ к рабочей области. Обратите внимание на идентификатор клиента (UUID) для роли Postgres и переменных окружения. | Создание субъекта-службы |
| Роль Postgres | Создайте роль OAuth в редакторе SQL Lakebase: databricks_create_role('{client-id}', 'SERVICE_PRINCIPAL') и предоставьте CONNECT, USAGE, SELECT/INSERT/UPDATE/DELETE. Используйте идентификатор клиента из шага 1. |
Создать роль Postgres |
| Сведения о подключении | Из консоли Lakebase Connect: имя конечной точки (projects/.../branches/.../endpoints/...), узел, база данных (обычно databricks_postgres). |
Получение сведений о подключении |
Принцип работы
Для подхода API вручную требуется два обмена токенами:
Время существования токена:
- Секрет служебного пользователя: До 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>.cloud.databricks.com"
export PGDATABASE="databricks_postgres"
export PGUSER="<service-principal-client-id>" # Same UUID as client ID
export PGPORT="5432"
Добавление кода подключения
завиток
В этом примере показаны необработанные вызовы 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) принимает асинхронную функцию в качестве пароля. Функция вызывается каждый раз при создании нового подключения, обеспечивая свежие токены.
Запуск и проверка подключения
завиток
Запустите скрипт 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 соответствует идентификатору клиента сервисного принципала, значит, OAuth работает правильно.
Node.js
Установите зависимости:
npm install pg
Запустить:
node app.js
Ожидаемые выходные данные:
Connected as: c00f575e-d706-4f6b-b62c-e7a14850571b
Примечание: Первое подключение после простоя может занять больше времени, так как автомасштабирование Lakebase начинает вычисление с нуля.
Устранение неполадок
| Ошибка | Исправить |
|---|---|
| "invalid_client" или "Отсутствует проверка подлинности клиента" | Проверьте, что DATABRICKS_CLIENT_ID и DATABRICKS_CLIENT_SECRET корректны. Используйте базовую проверку подлинности (в кодировке Base64). |
| "API отключен для пользователей без прав доступа к рабочей области" | Включите "Доступ к рабочей области" для субъекта-службы (предварительные требования). |
| "INVALID_PARAMETER_VALUE" / "Поле "конечная точка" является обязательным" | Убедитесь, что параметр endpoint включен в тело POST-запроса на шаге 2 с форматом projects/<id>/branches/<id>/endpoints/<id>. |
| Роль не существует или проверка подлинности завершается ошибкой | Создайте роль OAuth с помощью SQL (предварительные требования). |
| "Отклонено подключение" или время ожидания | Первое подключение после масштабирования до нуля может занять больше времени. Реализуйте логику повторных попыток. |
| Истек срок действия токена / "Сбой проверки подлинности пароля" | Срок действия маркеров рабочей области и базы данных истекает через 60 минут. Реализуйте кэширование с проверками срока действия. |