An Introduction to Tableau Hyper Extract and Tableau Hyper API

Natchapol Laowiwatkasem
CJ Express Tech (TILDI)
8 min readMar 11, 2024

หากพูดถึงเครื่องมือในการทำ Data Visualization หนึ่งในเครื่องมือที่นิยมอันดับต้นๆคงหนีไม่พ้น “Tableau” ในบทความนี้จะกล่าวถึง Hyper Extract ตั้งแต่ Hyper Extract คืออะไร, เราสามารถสร้าง Hyper Extract ได้อย่างไร, และเราจะนำไปใช้บน Tableau Cloud/ Server ได้อย่างไร

An Introduction to Tableau Hyper Extract and Tableau Hyper API

Table of Contents

  • What is Tableau Data Extracts?
  • What is Tableau Hyper Extract?
  • What is Tableau Hyper API?
  • How to build Hyper file with Python?
  • How to publish Hyper file to Tableau Cloud/ Server?

What is Tableau Data Extracts?

Tableau สามารถเชื่อมต่อ data sources ได้หลากหลายรูปแบบ โดยแบ่งการเชื่อมต่อออกได้ 2 ประเภท คือ Live Connections และ Data Extracts

Live Connections คือ การเชื่อมต่อเข้ากับ data source โดยตรง ซึ่ง Tableau จะ query data จาก source เหล่านี้แบบ real-time ในทุกๆครั้งที่เรา interact กับ visualization เหมาะกับงานประเภท real-time analytics แต่อาจมีปัญหาเรื่อง performance หากทำงานกับ data ขนาดใหญ่ได้

Data Extracts คือ snapshot ของ data ที่ถูก optimized มาสำหรับการทำ aggregation ต่างๆและจะถูกโหลดลง memory เพื่อให้เรียกใช้งานแสดง visualization ได้อย่างรวดเร็ว ทำให้ Data Extracts มีแนวโน้มที่จะเร็วกว่า Live Connections เมื่อทำงานกับข้อมูลขนาดใหญ่หรือมี complex visualization

Tableau ไม่ต้องการ database เพื่อเก็บ data ไว้แสดง visualization เพราะ Tableau มี in-memory data engine สำหรับ query จาก Data Extract โดยตรง อย่างไรก็ตาม Data Extract คือ snapshot ของ data ณ เวลาหนึ่งๆ จึงต้องมีการ refresh เพื่อ update ข้อมูลจาก data source เสมอ

What is Tableau Hyper Extract?

Tableau Hyper คือ Tableau’s In-Memory Data Engine ที่ถูกสร้างมาทดแทน Tableau Data Engine (TDE) ตั้งแต่ Tableau 10.5 ในแง่ของ performance ที่สามารถทำได้ดีกว่ามาก โดยเฉพาะเมื่อทำงานกับ data ขนาดใหญ่หรือ complex visualization

ก่อนอธิบายเพิ่มเติม เราควรเข้าใจ File Types ต่างๆของ Tableau เบื้องต้นก่อน

  • .twb (Tableau Workbook): เป็น workbook ที่เก็บงานของเรา เช่น worksheets, dashboards รวมไปถึง data source แต่ไม่เก็บ data
  • .twbx (Tableau Packaged Workbook): เหมือนกับ .twb แต่เก็บ data ด้วย เหมาะกับเคสที่ใช้แชร์ให้คนอื่นไม่สามารถเข้าถึง data ได้
  • .hyper (Tableau Data Extract): เก็บ snapshot ของ data ซึ่งนำไปแชร์ให้คนอื่นได้ หรือเก็บไว้ทำงานแบบ offline ได้เช่นกัน รวมไปถึงการใช้ Data Extract จะช่วยเพิ่ม performance ให้อีกด้วย
  • .tds (Tableau Data Source): เก็บข้อมูลที่เกี่ยวกับการเชื่อมต่อกับ data แต่ไม่ได้เก็บ data จริง และเก็บข้อมูลที่เราทำเพิ่ม เช่น calculated field เหมาะกับใช้เชื่อมต่อกับ data source ที่ใช้งานบ่อยๆ
  • .tdsx (Tableau Packaged Data Source): เหมือนกับ .tds แต่เก็บ data บน local ของเราด้วย เช่น .hyper, .csv เหมาะกับใช้แชร์ให้คนอื่นที่ไม่สามารถเข้าถึง data บนเครื่องเราได้
File Types ประเภทต่างๆกับการเก็บข้อมูลของ Tableau

เพราะฉะนั้น Hyper คือ technology หนึ่งของ Tableau ที่เป็น in-memory data engine ส่วน “ .hyper file format คือ Data Extract ที่เก็บ data ของเรา ” โดยสามารถเก็บแบบ normalized หรือ denormalized ก็ได้ แต่ .hyper file ไม่ได้เก็บแค่ data อย่างเดียว มันยังทำหน้าที่เป็นเหมือน SQL database ได้อีกด้วย

โครงสร้าง .hyper file 3 รูปแบบ

รูปข้างต้นแสดงถึง extract file 3 รูปแบบ โดยเป็นโครงสร้างของ .hyper file ที่ซึ่ง .hyper file ถูกออกแบบมาให้คล้ายคลึงกับ PostgreSQL หากใครได้ลองใช้งานแล้วจะพบว่า SQL syntax ส่วนมากเหมือนกับ PostgreSQL เลย

  • รูปซ้ายสุด: โครงสร้างโดยทั่วไปของ .hyper file ซึ่ง 1 .hyper file สามารถมีได้หลาย schema และภายใน 1 schema ก็มีได้หลาย tables เช่นกัน
  • รูปกลาง: โครงสร้างของ .hyper file ที่สร้างจาก Tableau โดย schema จะต้องสะกดว่า “Extract” เท่านั้น เพราะ naming ต่างๆเป็น case sensitive และชื่อ table จะเป็นชื่อตามที่เราตั้งใน Tableau
  • รูปขวาสุด: โครงสร้างของ .hyper file ที่สร้างจาก Hyper API โดย default แล้วชื่อ schema เป็น public ตาม PostgreSQL (สามารถเปลี่ยนได้) และสามารถมีได้หลาย table

What is Tableau Hyper API?

Tableau Hyper API เป็น library ที่ทำให้เราสามารถทำงานกับ .hyper file ได้ ซึ่งรองรับหลายภาษา เช่น Python, C++, Java โดยสามารถดูวิธีติดตั้งสำหรับแต่ละภาษาและ platform ได้ที่นี่

ก่อนเราไปใช้งาน Tableau Hyper API เพื่อจัดการ .hyper file เราลองมาดูโครงสร้างของ Hyper API กัน

โครงสร้างของ Tableau Hyper API

โครงสร้างของ Hyper API จะมี front end ที่เป็น wrapper ครอบ back end เพื่อให้รองรับการใช้งานได้กับหลายภาษา จากนั้น back end จะคุยกับ Hyper database server (hyperd) ด้วย SQL ซึ่งทำงานอยู่บน .hyper file โดยอยู่บน local ทั้งหมด

เมื่อเราเริ่มใช้งาน Hyper API สิ่งแรกที่ต้องทำ คือ การสร้าง instance ของ Hyper server โดยใช้ class HyperProcess โดย 1 instance สามารถเชื่อมต่อได้หลาย .hyper file ผ่าน class Connection ซึ่งสามารถมีได้หลาย connections และภายใน 1 connection สามารถเชื่อมต่อได้หลาย .hyper file แต่ไม่สามารถใช้หลาย connections เชื่อมต่อกับ .hyper file เดียวกันได้

ในหัวข้อถัดไปเราจะเริ่มสร้าง .hyper file ด้วย Python โดยใช้ Tableau Hyper API library กัน

How to Build a Hyper File with Python?

ด้วยตัวของ Hyper เองคือ standalone database server ซึ่ง Hyper API สามารถสร้าง Hyper server ได้ผ่าน HyperProcess class ซึ่งมี parameter ชื่อ telemetry ที่ปกติจะเปิดเพื่อส่งข้อมูลการใช้งานไปยัง Tableau แต่แนะนำให้ปิดไว้เพื่อความมั่นใจในความปลอดภัยเมื่อทำงานกับ data ขององค์กร

Note: เราควรใช้ with statement เมื่อใช้งานทุกครั้ง เพื่อให้มั่นใจว่า objects ต่างๆที่ถูกสร้างจาก Hyper API จะถูกทำลายเมื่อสิ้นสุดการใช้งาน

from tableauhyperapi import HyperProcess, Telemetry

with HyperProcess(telemetry=Telemetry.DO_NOT_SEND_USAGE_DATA_TO_TABLEAU) as hyper:
# do something

หลังจากเราสร้าง instance ของ Hyper server แล้ว ถัดมาเราจะสร้าง connection ไปยัง .hyper file ซึ่งประกอบด้วย 3 parameters หลักๆคือ

  • endpoint ไปยัง Hyper server
  • database คือ path ไปยัง .hyper file ที่มีอยู่แล้วหรือที่ต้องการสร้างใหม่
  • create_mode มี 4 แบบ ได้แก่ none, create, create and replace, create if not exists
from tableauhyperapi import HyperProcess, Telemetry, Connection, CreateMode

with HyperProcess(telemetry=Telemetry.DO_NOT_SEND_USAGE_DATA_TO_TABLEAU) as hyper:
with Connection(
endpoint=hyper.endpoint,
database="demo.hyper",
create_mode=CreateMode.CREATE_AND_REPLACE,
) as connection:
# do something

ในการทำงานกับ .hyper file ทุกๆครั้งเราต้องสร้าง 2 สิ่งนี้ขึ้นมาเสมอ หลังจากนั้นเราจึงจะเริ่มทำงานกับ .hyper file ได้ ซึ่งมี 2 วิธี คือ ผ่าน SQL โดยตรง หรือใช้ class ของ Hyper API โดยเบื้องหลังจะไปแปลงเป็น SQL ให้อีกที

ขั้นถัดมาเรามาลองสร้าง table และ insert data เข้าไปยัง .hyper file กัน

from tableauhyperapi import HyperProcess, Telemetry, Connection, CreateMode, TableDefinition, TableName, SqlType, Nullability, Inserter


with HyperProcess(telemetry=Telemetry.DO_NOT_SEND_USAGE_DATA_TO_TABLEAU) as hyper:
with Connection(endpoint=hyper.endpoint, database="demo.hyper", create_mode=CreateMode.CREATE_AND_REPLACE) as connection:
# create table definition
demo_table = TableDefinition(
table_name=TableName("demo_table"),
columns=[
TableDefinition.Column("id", SqlType.text(), Nullability.NOT_NULLABLE),
TableDefinition.Column("name", SqlType.text(), Nullability.NOT_NULLABLE),
TableDefinition.Column("points", SqlType.int(), Nullability.NULLABLE),
],
)
# create table
connection.catalog.create_table(demo_table)

# insert data
with Inserter(connection, demo_table) as inserter:
inserter.add_row(["1", "VER", 575])
inserter.add_row(["2", "PER", 285])
inserter.execute()

ในการสร้าง table เราจะต้องสร้าง schema ของ table ขึ้นมาก่อน โดยใช้ TableDefinition class และตั้งชื่อ table ด้วย TableName class พร้อม columns ที่ต้องการ หากเราระบุแค่ชื่อ table โดยปกติแล้วชื่อ schema จะเป็น public โดยอัตโนมัติ และในการระบุ columns ให้ใส่ชื่อ column, data type, และ nullability

ตัวอย่างข้างต้นจะเป็นการสร้าง table ชื่อ demo_table ที่มี 3 columns ได้แก่ id, name เป็น text และห้ามมี null ส่วน points เป็น int แต่สามารถมีค่า null ได้

เมื่อสร้าง schema ของ table เสร็จแล้วให้ใช้ create_table method ของ Catalog class ในการสร้าง table จากนั้นจึง insert data เข้าไป โดยสร้าง object จาก Inserter class ซึ่งต้องระบุ table ที่ต้องการแล้ว insert data เข้าไปทีละแถว สุดท้ายเรียก execute เพื่อ commit data ที่จะเพิ่มเข้าไป

ภาพจาก Tableau เมื่อเปิด .hyper file ที่เพิ่งสร้างเมื่อสักครู่

เมื่อลองเข้า Tableau โดยเลือก demo.hyper ที่เพิ่งสร้าง จะพบว่ามี demo_table ที่เราสร้างไว้ โดยมี 3 columns 2 rows ตามที่เราต้องการ สังเกตได้ว่าชื่อ schema จะเป็น public โดย default ให้เอง

อย่างที่ได้กล่าวไปข้างต้น เราสามารถเขียน SQL เพื่อทำงานกับ .hyper file ได้โดยตรง ตัวอย่างต่อไปเราจะลอง insert data เพิ่ม 1 row ใส่ demo_table

# insert data using SQL
row_count = connection.execute_command(
f"""
INSERT INTO {TableName("demo_table")}
VALUES('3', 'HAM', 234)
"""
)
print(row_count)

วิธีนี้ถือว่าสะดวกมากๆสำหรับผู้ที่ใช้งาน SQL อยู่แล้ว เพราะ .hyper file ออกแบบมาให้คล้ายกับ PostgreSQL สามารถดู SQL reference ได้ที่นี่

ภาพจาก Tableau หลัง insert data เข้าไป 1 row ด้วย SQL

ผลลัพธ์หลังจาก insert data ด้วย SQL แล้ว แสดงให้เห็นว่าเราสามารถใช้ SQL command ในการทำงานกับ .hyper file ได้เช่นเดียวกับใช้ class ต่างๆของ Hyper API

สิ่งหนึ่งที่น่าจะสังเกตได้ คือ เราต้อง insert data ทีละแถวเข้า .hyper file แต่ในการทำงานจริงเรามี data มหาศาล การ insert data ทีละแถวถือว่าไม่มีประสิทธิภาพ ดังนั้นหากเรามีไฟล์ที่เก็บข้อมูลอยู่แล้ว อีกหนึ่งทางเลือกที่ดีกว่าคือการใช้ “COPY FROM” ซึ่งจะ copy data จากไฟล์ของเราเข้า .hyper file ได้เลย

with HyperProcess(telemetry=Telemetry.DO_NOT_SEND_USAGE_DATA_TO_TABLEAU) as hyper:
with Connection(endpoint=hyper.endpoint, database="demo.hyper", create_mode=CreateMode.CREATE_AND_REPLACE) as connection:
# create table definition
demo_table = TableDefinition(
table_name=TableName("demo_table"),
columns=[
TableDefinition.Column("id", SqlType.text(), Nullability.NOT_NULLABLE),
TableDefinition.Column("name", SqlType.text(), Nullability.NOT_NULLABLE),
TableDefinition.Column("points", SqlType.int(), Nullability.NULLABLE)
]
)
# create table
connection.catalog.create_table(demo_table)

# insert data using COPY FROM
row_count = connection.execute_command(
f"""
COPY {TableName("demo_table")}
FROM {escape_string_literal("demo.csv")}
WITH (format csv, delimiter ',', header)
"""
)
print(row_count)

ขั้นตอนยังคล้ายเดิม เราแค่เขียน SQL command ในการ copy data จาก csv file ได้เลย

ภาพจาก Tableau หลังจาก copy data จาก csv file

ผลลัพธ์หลังจากการ copy data จาก demo.csv เข้า .hyper file ซึ่งได้ผลเช่นเดียวกับการเพิ่มทีละแถว โดยวิธีนี้สามารถใช้ได้กับ .csv, .parquet รวมไปถึง iceberg (early stage of development) และยังรองรับการอ่านไฟล์จาก Amazon S3 อีกด้วย (ปัจจุบันยังไม่รองรับ cloud provider เจ้าอื่นๆ)

โดยตัวอย่างข้างต้นเป็นเพียงส่วนหนึ่งของการทำงานกับ .hyper file โดย operation พื้นฐานอย่าง CRUD สามารถทำได้ทั้งหมด แต่ถ้าเราทำงานกับ pandas dataframe อยู่แล้ว อีกหนึ่ง library ที่แนะนำ คือ “pantab” โดย library นี้สะดวกมากๆ เพราะสามารถแปลง pandas dataframe ออกมาเป็น .hyper file ได้เลย

import pandas as pd
import pantab as pt


df = pd.read_csv("demo.csv")
pt.frame_to_hyper(df=df, database="demo.hyper", table="demo_pantab")

เพียงแค่ 2 บรรทัดโดยอ่านเป็น dataframe และแปลงเป็น .hyper file ก็จะได้ผลลัพธ์เช่นเดียวกับการใช้ Hyper API

ภาพจาก Tableau โดยใช้ pantab library ในการแปลงเป็น .hyper file

ผลลัพธ์ที่ได้ออกมาแทบจะเหมือนกับการใช้ Hyper API และ pantab ยังเคลมว่าตัวเองเร็วกว่าการ insert data ด้วย Hyper API ปกติอีกด้วย เนื่องจากหลังบ้านใช้ C++ เข้ามาช่วยลดความช้าของ Python นั้นเอง แต่ข้อจำกัดของ library นี้คือ ไม่สามารถระบุ data type หรือ nullability ของ column ได้ สังเกตได้ว่า column ชื่อ id จากที่เราต้องการให้เป็น text กลับกลายเป็น number แทน

ในหัวข้อถัดไปหลังจากเราสร้าง .hyper file ได้แล้ว เราลองนำไป publish ขึ้น Tableau Cloud/ Server เพื่อใช้งานสร้าง dashboard ต่อไป

How to Publish Hyper File to Tableau Cloud/ Server?

วิธีการ publish .hyper file ไปยัง Tableau Cloud/ Server มี 2 วิธีที่สะดวกที่สุด คือ

  • ผ่าน Tableau Desktop โดย publish เป็น .twbx (workbook + data source + data) หรือ .tdsx (data source + data)
  • ผ่าน Tableau REST API หรือ Tableau Server Client (Python library) โดยวิธีนี้จะสามารถ publish .hyper file โดยไม่ต้อง pack เข้ากับ data source

ปัจจุบัน Tableau มี Personal Access Token (PAT) ที่แนะนำให้ใช้สำหรับ sign in ผ่าน REST API แทนที่การใช้ username/ password ในเวอร์ชันเก่าๆ แต่มีข้อจำกัดที่ 1 PAT สามารถเปิดได้ทีละ 1 session เท่านั้น

ในหัวข้อนี้จะแสดงตัวอย่างเฉพาะการ publish ผ่าน REST API โดยเริ่มจากใช้ REST API โดยตรง เนื่องจากวิธีนี้จะต้องเขียนโค้ดที่ค่อนข้างยาว จึงนำตัวอย่างของ Tableau มาแสดง ตัวอย่างนี้จะเป็นการ move data source ระหว่าง 2 server เราสามารถนำไปแก้ไขเพื่อใช้ในการ publish .hyper file ได้ ซึ่ง steps ในการ publish .hyper file ด้วย REST API คือ

  • sign in เข้าสู่ Tableau ด้วย Personal Access Token (PAT) เพื่อรับ auth token และ site id
  • นำ auth token และ site id ที่ได้ พร้อม project name ไปค้นหา project id ที่ต้องการ publish ไป
  • จากนั้นนำ auth token, site id และ project id ไปใช้ในการ publish .hyper file โดยมี file size limit ที่ 64 MB หาก .hyper file เราใหญ่กว่านั้น ให้แบ่งเป็นหลายๆส่วนแล้วทยอย upload แทน
  • สุดท้าย sign out เพื่อทำลาย auth token และปิด session ให้สามารถนำ PAT ไปใช้งานต่อได้

แต่ด้วยความยุ่งยากของวิธีนี้ทำให้มี library ที่มาครอบ REST API เพื่อจัดการสิ่งเหล่านี้ให้ คือ Tableau Server Client ทำให้การเขียนโค้ดเราสั้นลงและง่ายมากขึ้น

import tableauserverclient as TSC


tableau_auth = TSC.PersonalAccessTokenAuth(
token_name="your_token_name",
personal_access_token="your_token_value",
site_id="your_site_name",
)
server = TSC.Server("your_server_address", use_server_version=True)

with server.auth.sign_in(tableau_auth):
for project in TSC.Pager(server.projects):
if project.name == "your_project_name":
project_id = project.id

datasource = TSC.DatasourceItem(project_id)
publish_mode = TSC.Server.PublishMode.Overwrite
server.datasources.publish(datasource, "demo.hyper", publish_mode)

ในตัวอย่างข้างต้นเป็นการ publish demo.hyper ไปยัง Tableau Cloud ซึ่งมี parameter 5 อย่าง คือ

  • PAT token name
  • PAT token value
  • site name หากใช้ Tableau Cloud จะเป็นชื่อใน url หลัง /site/
  • server address คือ url ตั้งแต่ https:// จนถึง .tableau.com
  • project name คือ ชื่อของ project ที่ต้องการ publish ไป
เมื่อ published .hyper file ไปแล้วจะเป็น data source แบบ Live-to-Hyper
ภายใน data source อันใหม่จะพบ .hyper ที่เป็น data ของเราอยู่

เมื่อ publish .hyper file ขึ้นไปจะออกมาเป็น data source แบบ Live-to-Hyper connection โดยอัตโนมัติ เมื่อกดเข้าไปภายใน data source จะพบว่า owner คือชื่อเจ้าของ PAT และชื่อของ data source จะเป็นชื่อตาม .hyper file ที่ publish ขึ้นไปนั้นเอง

หลังจากนั้นเราจะสามารถนำ workbook มา connect กับ data source อันนี้เพื่อนำไปทำ dashboard, report ต่อไป

Conclusion

ในบทความนี้กล่าวถึง 3 ส่วนหลักๆ ได้แก่

  • Tableau Hyper Extract: เป็น data extract ของ Tableau ซึ่งเก็บ snapshot ของ data ณ เวลาหนึ่งๆ ต้องเกิดการ refresh เป็นระยะๆเพื่อให้ข้อมูลได้รับการอัพเดตให้ตรงกับ source เหมาะสำหรับการทำงานกับข้อมูลขนาดใหญ่และ complex visualization
  • Tableau Hyper API: เป็น library ที่ใช้ทำงานกับ .hyper file ซึ่งรองรับหลายภาษา โดยสามารถทำงานโดยผ่าน class ของ Hyper API หรือเขียน SQL โดยตรง ซึ่ง SQL command ส่วนมากจะคล้ายกับของ PostgreSQL หรือใช้ library pantab ในการแปลงจาก pandas dataframe เป็น .hyper file
  • การ publish .hyper file ไปยัง Tableau Cloud/ Server ด้วย Tableau Server Client library ของ Python รวมถึงวิธีการคร่าวๆของการ publish ผ่าน Tableau REST API

ในปัจจุบันการใช้งาน Extract ใน Tableau จะใช้ .hyper file ในการเก็บ data ของเรา

References

Thanks for reading. Hope you enjoy my blog :)

--

--