SQL Editor

Ctrl+Enter / Cmd+Enter 으로 실행
쿼리를 실행하면 결과가 여기에 표시됩니다

Analyst DuckDB API

분석가와 Airflow를 위한 DuckDB SQL API 서비스. JSON 데이터를 적재하고 SQL로 조회할 수 있습니다.

환경 구성

환경도메인클러스터네임스페이스용도
PRODduckdb.clobe.airevenue-datainsighter-prod운영 데이터 적재/조회
DEVduckdb.dev.clobe.aidev-data-k8sinsighter개발/테스트

접근 방법

1. 웹 브라우저 (분석가용)

Prod: https://duckdb.clobe.ai
Dev: https://duckdb.dev.clobe.ai

2. Airflow DAG에서 접근 (k8s 내부)

각 환경의 Airflow는 같은 클러스터/네임스페이스에서 실행되므로 내부 서비스 주소를 사용합니다.

Prod (revenue-data / insighter-prod):
http://analyst-duckdb.insighter-prod.svc.cluster.local:8000

Dev (dev-data-k8s / insighter):
http://analyst-duckdb.insighter.svc.cluster.local:8000

Airflow Connection 설정 (Admin > Connections):

FieldProdDev
Conn Idduckdb_apiduckdb_api
Conn TypeHTTPHTTP
Hosthttp://analyst-duckdb.insighter-prod.svc.cluster.localhttp://analyst-duckdb.insighter.svc.cluster.local
Port80008000

HttpOperator 사용 예시:

from airflow.providers.http.operators.http import HttpOperator
import json

ingest_task = HttpOperator(
    task_id="push_to_duckdb",
    http_conn_id="duckdb_api",
    endpoint="/api/ingest",
    method="POST",
    headers={"Content-Type": "application/json"},
    data=json.dumps({
        "table": "daily_revenue_stats",
        "data": "{{ ti.xcom_pull(task_ids='bq_aggregate') }}",
        "mode": "replace"
    }),
)

PythonOperator 사용 예시:

import requests

def push_to_duckdb(**ctx):
    data = ctx["ti"].xcom_pull(task_ids="bq_aggregate")
    # prod: insighter-prod / dev: insighter
    resp = requests.post(
        "http://analyst-duckdb.insighter-prod.svc.cluster.local:8000/api/ingest",
        json={"table": "daily_stats", "data": data, "mode": "replace"}
    )
    resp.raise_for_status()
    return resp.json()

3. 외부에서 curl / HTTP 클라이언트

# 데이터 조회 (prod)
curl -X POST https://duckdb.clobe.ai/api/sql \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT * FROM my_table LIMIT 10"}'

# 데이터 적재 (prod)
curl -X POST https://duckdb.clobe.ai/api/ingest \
  -H "Content-Type: application/json" \
  -d '{
    "table": "my_data",
    "data": [{"col1": "val1", "col2": 123}],
    "mode": "replace"
  }'

# 테이블 목록
curl https://duckdb.clobe.ai/api/tables

# 파일 업로드
curl -X POST https://duckdb.clobe.ai/api/upload \
  -F "file=@data.json" -F "table_name=my_data"
Dev 환경은 duckdb.dev.clobe.ai로 대체하세요.

API 레퍼런스

MethodPath설명
POST/api/sqlSQL 쿼리 실행
POST/api/ingestJSON 데이터 적재 (Airflow용)
POST/api/uploadJSON/CSV 파일 업로드
GET/api/tables테이블 목록 + 스키마 조회
DEL/api/tables/{name}테이블 삭제

POST /api/sql

SQL 쿼리를 실행하고 결과를 JSON으로 반환합니다.

// Request
{"sql": "SELECT * FROM daily_stats WHERE date >= '2026-02-01'"}

// Response
{
  "columns": ["date", "revenue", "orders"],
  "rows": [["2026-02-20", 1234567, 89], ...],
  "row_count": 20
}
차단되는 SQL: DROP DATABASE, ATTACH, COPY TO, EXPORT, IMPORT, LOAD, INSTALL

POST /api/ingest

JSON 배열 데이터를 DuckDB 테이블에 적재합니다. Airflow 배치에서 주로 사용합니다.

// Request
{
  "table": "daily_revenue_stats",   // 테이블명 (영숫자+언더스코어)
  "data": [                         // JSON 객체 배열
    {"date": "2026-02-20", "revenue": 1234567, "orders": 89},
    {"date": "2026-02-19", "revenue": 1111111, "orders": 76}
  ],
  "mode": "replace"                 // "replace" 또는 "append" (기본값: append)
}

// Response
{"table": "daily_revenue_stats", "rows_loaded": 2, "total_rows": 2, "mode": "replace"}

replace: 기존 테이블 DROP 후 새로 생성 (매일 전체 교체 시 사용)
append: 기존 테이블에 INSERT (증분 적재 시 사용)

POST /api/upload

JSON 또는 CSV 파일을 업로드하여 테이블을 생성합니다.

curl -X POST http://duckdb.clobe.ai/api/upload \
  -F "file=@report.json" \
  -F "table_name=quarterly_report"

// Response
{"table": "quarterly_report", "rows_loaded": 150, "columns": ["date", "metric", "value"]}

GET /api/tables

모든 테이블의 목록, 행 수, 컬럼 스키마를 반환합니다.

// Response
[
  {
    "name": "daily_stats",
    "row_count": 365,
    "columns": [
      {"name": "date", "type": "VARCHAR"},
      {"name": "revenue", "type": "BIGINT"},
      {"name": "orders", "type": "BIGINT"}
    ]
  }
]

DELETE /api/tables/{name}

지정된 테이블을 삭제합니다.

curl -X DELETE http://duckdb.clobe.ai/api/tables/old_data

// Response
{"deleted": "old_data"}

인프라 정보

항목ProdDev
클러스터revenue-datadev-data-k8s
네임스페이스insighter-prodinsighter
도메인duckdb.clobe.aiduckdb.dev.clobe.ai
내부 주소analyst-duckdb.insighter-prod.svc.cluster.local:8000analyst-duckdb.insighter.svc.cluster.local:8000
데이터 저장PersistentVolumeClaim (10Gi, GCE Persistent Disk)
파일 업로드 제한100MB
인증없음 (내부 네트워크 접근 전제)