Tableau Server 메타데이터 저장소
•
Tableau Server/Online은 PostgreSQL 기반 Repository(DB)를 내장하고 있음
•
이 DB 안에는 대시보드/워크북/데이터소스/스케줄 실행 로그 같은 메타데이터 테이블이 저장됨
•
주요 테이블:
◦
workbooks: 워크북(대시보드)의 정의, 이름, 소유자 등
◦
datasources: 데이터소스 정의 (연결 정보, 스키마 등)
◦
schedules: 예약 실행 스케줄
◦
tasks: 실행해야 하는 태스크(추출 리프레시, 플로우 실행 등)
◦
background_jobs: 실제 백그라운드에서 실행된 잡(성공/실패, 에러 메시지 등)
◦
flow_runs: Tableau Prep Flow 실행 이력 (flow_id, completed_at, finish_code 등)
TDS / TDSX 파일
•
TDS (Tableau Data Source):
◦
단순히 데이터소스 정의(연결정보, 필드 정의, 계산식, Alias 등)를 담은 XML 파일
◦
실제 데이터는 포함하지 않음
•
TDSX (Packaged Data Source):
◦
.tds + 데이터 추출(.hyper 파일) + 기타 메타데이터를 압축한 패키지 파일 (ZIP 기반)
◦
Tableau Desktop/Server에서 내보내거나 다운로드할 수 있음
◦
구조 예시:
my_datasource.tdsx
├── Data/
│ └── Extracts/
│ └── hyper_0.hyper # 실제 데이터 (columnar DB 형태)
└── my_datasource.tds # 데이터소스 정의(XML)
Plain Text
복사
◦
.tdsx 압축을 풀면 Hyper 파일을 얻을 수 있고, 거기서 데이터를 쿼리 가능
Hyper 파일
•
Tableau의 in-memory columnar database 포맷 (.hyper)
•
Parquet과 유사하게 컬럼 지향 저장 → 분석 쿼리에 최적화
•
Python에서는 tableauhyperapi 패키지를 이용해 직접 조회 가능
from tableauhyperapi import HyperProcess, Connection, TableName
with HyperProcess(telemetry=Telemetry.SEND_USAGE_DATA_TO_TABLEAU) as hyper:
with Connection(endpoint=hyper.endpoint, database="hyper_0.hyper") as connection:
result = connection.execute_list_query("SELECT * FROM Extract.LOD_TABLE")
print(result[:10])
Python
복사
•
Airflow에서 굳이 Hyper API까지 안 쓰고 Pandas로 변환하거나 CSV 추출만 해도 충분
Tableau API vs Repository SQL
•
Tableau Server Client (TSC) API
◦
공식 Python 라이브러리 (tableauserverclient)
◦
로그인/세션 관리, 데이터소스/워크북/스케줄 조회 가능
◦
REST API 기반 → Tableau Server 보안 정책 준수, 권한 관리도 그대로 적용
import tableauserverclient as TSC
from dotenv import load_dotenv
import os
load_dotenv()
tableau_server_address = os.getenv("server_address")
tableau_username = os.getenv("username")
tableau_password = os.getenv("password")
server = TSC.Server(
server_address=tableau_server_address,
use_server_version=True
)
auth = TSC.TableauAuth(
username=tableau_username,
password=tableau_password,
)
endpoint = "https://airflow.mycorp.co.kr/api/tableau_refresh"
datasource_id = "e7da98eb-1b7c-41e7-b3ae-248c90fc0c97"
with server.auth.sign_in(auth):
ds = server.datasources.get_by_id(datasource_id)
print(ds)
schedules, _ = server.schedules.get()
print(schedules)
Bash
복사
•
Repository SQL (Postgres 직접 조회)
◦
Tableau Server 내부 Postgres에 직접 접속
◦
더 저수준 로그와 실행 이력을 바로 가져올 수 있음
◦
단점: 스키마 변경에 취약 (Tableau 버전 업 시 컬럼명이 바뀌기도 함)
from airflow.providers.postgres.hooks.postgres import PostgresHook
from dotenv import load_dotenv
import os
load_dotenv()
datasource_id = "e7da98eb-1b7c-41e7-b3ae-248c90fc0c97"
schedule_query = f"""
SELECT *
from schedules
WHERE id = 721
"""
task_query = f"""
SELECT *
FROM tasks
WHERE id = 3585
-- where type = 'RefreshExtractTask' and obj_type = 'Datasource'
"""
background_query = f"""
SELECT *
FROM background_jobs
where id = 11917568
"""
workbook_query = f"""
SELECT * FROM workbooks WHERE name LIKE '%기준가%';
"""
query = f"""
SELECT
*
FROM flow_runs
WHERE flow_id = 3707
ORDER BY completed_at DESC
LIMIT 1
"""
with PostgresHook(postgres_conn_id="tableau").get_conn() as conn:
with conn.cursor() as cursor:
cursor.execute(query)
rows = cursor.fetchall()
col_names = [d.name for d in cursor.description]
for row in rows:
print(list(zip(col_names, row)))
Bash
복사
요약
•
Tableau Data Source는 .tds (정의만 포함)와 .tdsx (정의 + Hyper 추출 데이터) 형태로 존재
•
.tdsx는 ZIP 패키지로, 압축 해제하면 hyper_0.hyper 파일(컬럼 지향 DB 포맷)과 .tds 파일(XML 정의)을 얻을 수 있음
•
Hyper 파일은 Tableau 전용 in-memory DB 포맷으로, tableauhyperapi Python 라이브러리로 직접 쿼리 가능