외부 데이터 조회
외부 작업은 서비스 계정의 액세스 토큰으로 D.Hub 데이터 조회 API를 호출하고, 반환된 데이터를 파일이나 외부 데이터베이스에 저장합니다. 데이터셋 전체를 내려받거나 SQL로 필요한 행만 조회합니다.
D.Hub가 데이터 변경을 외부 데이터베이스로 밀어내거나 변경 이벤트를 제공하지는 않습니다. 짧은 주기로 조회 작업을 실행하면 반영 지연을 줄일 수 있지만 실시간 전달을 보장하지 않습니다.
준비하기
- 서비스 계정에서 외부 연동 전용 계정을 만들고 액세스 토큰을 발급합니다.
- 대상 데이터셋의 공유 및 권한에서 서비스 계정을 선택하고 뷰어 역할을 부여합니다. 컬렉션의 뷰어 역할을 부여하면 하위 데이터셋에도 읽기 권한이 상속됩니다.
- 데이터셋 개요 탭의 ID를 복사합니다.
- SQL로 조회하려면 데이터셋 데이터 탭의 쿼리 가이드에서 데이터베이스, 테이블, 예시를 확인합니다.
- D.Hub API 기본 주소, 데이터셋 ID, 액세스 토큰을 외부 작업의 설정과 비밀 값 저장소에 등록합니다.
영역: 데이터셋 데이터 탭에서 SQL 편집기를 펼쳐 쿼리 가이드의 데이터베이스·테이블·예시가 표시된 상태.
다음 셸 설정은 토큰을 명령 기록에 남기지 않습니다. 자동 실행 환경에서는 같은 값을 CI/CD 또는 작업 스케줄러의 비밀 값으로 주입합니다.
export DHUB_API_BASE_URL="https://{host}/api/v1"
export DHUB_DATASET_ID="{dataset_id}"
read -rsp "D.Hub access token: " DHUB_ACCESS_TOKEN
export DHUB_ACCESS_TOKEN
echo
조회 API 선택하기
| 목적 | API | 주요 옵션 |
|---|---|---|
| 전체 데이터 또는 제한된 행을 파일·JSON으로 받기 | Get Table — GET /datasets/{table_id}/table | format, limit, version |
| 컬럼 선택·필터·정렬·집계 결과 받기 | Query Table — POST /datasets/{table_id}/table/query | format, 본문의 query, limit |
Get Table은 csv, json, parquet, arrow 형식을 지원합니다. limit을 생략하면 전체 데이터를 반환하므로 먼저 작은 값으로 응답 크기와 처리 시간을 확인합니다. version은 버전 관리되는 데이터셋에서 버전 기록에 표시된 데이터 버전을 조회할 때만 사용합니다.
Query Table은 데이터셋 데이터 탭과 같은 ClickHouse SELECT 문을 사용합니다. 요청 본문의 limit은 반환 행 수를 제한하며 다음 페이지를 가리키는 커서를 만들지 않습니다.
데이터셋 내려받기
cURL
다음 요청은 현재 데이터에서 최대 100행을 JSON 배열로 반환합니다.
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer ${DHUB_ACCESS_TOKEN}" \
"${DHUB_API_BASE_URL}/datasets/${DHUB_DATASET_ID}/table?format=json&limit=100"
파일로 보관하려면 format과 출력 파일 확장자를 맞춥니다.
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer ${DHUB_ACCESS_TOKEN}" \
"${DHUB_API_BASE_URL}/datasets/${DHUB_DATASET_ID}/table?format=parquet" \
--output dataset.parquet
Python
import os
import requests
base_url = os.environ["DHUB_API_BASE_URL"]
dataset_id = os.environ["DHUB_DATASET_ID"]
token = os.environ["DHUB_ACCESS_TOKEN"]
response = requests.get(
f"{base_url}/datasets/{dataset_id}/table",
headers={"Authorization": f"Bearer {token}"},
params={"format": "json", "limit": 100},
timeout=60,
)
response.raise_for_status()
rows = response.json()
필요한 행만 SQL로 조회하기
다음 예제는 updated_at 이후에 바뀐 행을 오래된 순서로 최대 1,000개 조회합니다. {database}, {table}, 컬럼 이름과 기준 시각은 대상 데이터셋에 맞게 바꿉니다.
cURL
QUERY="SELECT id, updated_at, value
FROM \`{database}\`.\`{table}\`
WHERE updated_at >= '2026-07-24T00:00:00Z'
ORDER BY updated_at, id"
jq -n --arg query "${QUERY}" \
'{query: $query, limit: 1000}' | \
curl --fail-with-body --silent --show-error \
-X POST \
-H "Authorization: Bearer ${DHUB_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
--data-binary @- \
"${DHUB_API_BASE_URL}/datasets/${DHUB_DATASET_ID}/table/query?format=json"
Python
query = """
SELECT id, updated_at, value
FROM `{database}`.`{table}`
WHERE updated_at >= '2026-07-24T00:00:00Z'
ORDER BY updated_at, id
"""
response = requests.post(
f"{base_url}/datasets/{dataset_id}/table/query",
headers={"Authorization": f"Bearer {token}"},
params={"format": "json"},
json={"query": query, "limit": 1000},
timeout=60,
)
response.raise_for_status()
rows = response.json()
URL의 데이터셋 ID와 SQL의 데이터베이스·테이블은 같은 데이터셋을 가리켜야 합니다. 데이터셋 데이터 탭의 쿼리 가이드에 표시된 값을 사용하고 SELECT 문만 실행합니다.
외부 데이터베이스에 주기적으로 반영하기
외부 작업이 일정에 따라 API를 호출하고 대상 데이터베이스에 반영합니다.
- 마지막으로 성공한 워터마크를 불러옵니다. 일반적으로 수정 시각과 중복되지 않는 ID를 함께 사용합니다.
Query Table에서 워터마크 이후의 행을 정렬해 조회합니다. 같은 시각의 행을 놓치지 않도록 이전 기준과 일부 겹치게 조회할 수 있습니다.- 대상 데이터베이스에서 안정적인 키를 기준으로 upsert합니다. PostgreSQL은
INSERT ... ON CONFLICT, MySQL은INSERT ... ON DUPLICATE KEY UPDATE, 다른 데이터베이스는 동등한MERGE기능을 사용합니다. - 대상 데이터베이스의 트랜잭션이 커밋된 뒤 가장 큰 수정 시각과 ID를 새 워터마크로 저장합니다.
- 결과가
limit에 도달하면 마지막 행을 새 시작점으로 사용해 다음 묶음을 계속 조회합니다.
작업이 중간에 실패하면 기존 워터마크부터 다시 조회합니다. 중복 행이 포함되어도 같은 결과가 되도록 upsert 키와 업데이트 규칙을 정합니다. API 호출 재시도에는 지수 백오프를 사용하고, 대상 데이터베이스 커밋 전에 워터마크를 갱신하지 않습니다.
- 데이터셋에 신뢰할 수 있는 수정 시각이나 증가 키가 없으면 변경된 행만 구분할 수 없습니다. 이 경우 전체 스냅샷을 다시 가져와 비교합니다.
- 조회 API는 삭제 이벤트나 공통 변경 커서를 제공하지 않습니다. 삭제 반영이 필요하면 원본에 삭제 상태 컬럼을 두거나 일정 주기로 전체 대조 작업을 실행합니다.
- 짧은 실행 주기는 지연을 줄일 뿐, 네트워크·API 처리·대상 데이터베이스 커밋 시간을 포함한 실시간 반영을 보장하지 않습니다.
오류와 토큰 운영
| 증상 | 확인할 항목 |
|---|---|
401 Unauthorized | Bearer 접두사, 토큰 만료·폐기 여부 |
403 Forbidden | 서비스 계정의 데이터셋 뷰어 이상 권한과 분류 라벨 접근 인가 |
404 Dataset not found | 데이터셋 개요 탭에서 복사한 ID인지 확인 |
| SQL 또는 요청 형식 오류 | 쿼리 가이드의 데이터베이스·테이블, SELECT 문, JSON의 query 필드 확인 |
| 응답 지연 또는 메모리 부족 | limit을 줄이고 워터마크와 안정적인 키로 조회 범위를 나눔 |
토큰은 소스 코드, 로그, 작업 출력에 기록하지 않습니다. 토큰을 교체할 때는 새 토큰을 외부 작업에 먼저 반영하고 호출 성공을 확인한 뒤 이전 토큰을 폐기합니다. 상태 코드와 공통 응답 형식은 오류 처리에서 확인합니다.