Search

Tableau 메타데이터 다루기

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 라이브러리로 직접 쿼리 가능