Tableau Integration
Tableau is a leading business intelligence platform for data visualization and analytics. Olytix Core integrates with Tableau through the REST API, enabling live queries against your semantic layer with consistent metric definitions.
Integration Methods
| Method | Use Case | Data Freshness |
|---|---|---|
| REST API | Custom Web Data Connector | Live |
| JDBC/ODBC | Direct SQL access | Live |
| Hyper Extract | Pre-built extracts | Scheduled |
Prerequisites
- Tableau Desktop 2020.4+ or Tableau Server/Cloud
- Olytix Core API server running and accessible
- API key or authentication configured
REST API Integration
Web Data Connector
The recommended approach is using a custom Web Data Connector (WDC) that queries Olytix Core's REST API.
WDC Setup
- Deploy the Olytix Core WDC to a web server:
<!-- olytix-core-wdc.html -->
<!DOCTYPE html>
<html>
<head>
<title>Olytix Core Connector</title>
<script src="https://connectors.tableau.com/libs/tableauwdc-2.3.latest.js"></script>
</head>
<body>
<div id="config">
<h2>Olytix Core Connection</h2>
<label>API URL: <input type="text" id="apiUrl" value="http://localhost:8000"></label><br>
<label>API Key: <input type="password" id="apiKey"></label><br>
<label>Cube: <input type="text" id="cube" value="orders"></label><br>
<button id="connect">Connect</button>
</div>
<script>
(function() {
var myConnector = tableau.makeConnector();
myConnector.getSchema = function(schemaCallback) {
var connectionData = JSON.parse(tableau.connectionData);
fetch(connectionData.apiUrl + '/api/v1/cubes/' + connectionData.cube + '/schema', {
headers: { 'Authorization': 'Bearer ' + tableau.password }
})
.then(response => response.json())
.then(schema => {
var cols = schema.dimensions.map(d => ({
id: d.name,
alias: d.name,
dataType: mapDataType(d.type)
})).concat(schema.measures.map(m => ({
id: m.name,
alias: m.name,
dataType: tableau.dataTypeEnum.float
})));
var tableInfo = {
id: connectionData.cube,
alias: connectionData.cube,
columns: cols
};
schemaCallback([tableInfo]);
});
};
myConnector.getData = function(table, doneCallback) {
var connectionData = JSON.parse(tableau.connectionData);
fetch(connectionData.apiUrl + '/api/v1/query', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + tableau.password,
'Content-Type': 'application/json'
},
body: JSON.stringify({
cube: connectionData.cube,
measures: connectionData.measures,
dimensions: connectionData.dimensions
})
})
.then(response => response.json())
.then(result => {
table.appendRows(result.data);
doneCallback();
});
};
function mapDataType(olytix-coreType) {
switch(olytix-coreType) {
case 'string': return tableau.dataTypeEnum.string;
case 'number': return tableau.dataTypeEnum.float;
case 'time': return tableau.dataTypeEnum.datetime;
case 'boolean': return tableau.dataTypeEnum.bool;
default: return tableau.dataTypeEnum.string;
}
}
tableau.registerConnector(myConnector);
document.getElementById('connect').addEventListener('click', function() {
tableau.connectionData = JSON.stringify({
apiUrl: document.getElementById('apiUrl').value,
cube: document.getElementById('cube').value
});
tableau.password = document.getElementById('apiKey').value;
tableau.connectionName = 'Olytix Core - ' + document.getElementById('cube').value;
tableau.submit();
});
})();
</script>
</body>
</html>
- In Tableau Desktop, select Web Data Connector from the connection pane
- Enter the URL to your WDC HTML file
- Configure the connection parameters
Direct REST API Usage
For custom workflows, query Olytix Core directly and import the results:
# tableau_export.py
import requests
import pandas as pd
import pantab
# Query Olytix Core
response = requests.post(
"http://localhost:8000/api/v1/query",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"metrics": ["total_revenue", "order_count"],
"dimensions": ["region", "product_category", "order_date.month"],
"filters": [
{"dimension": "order_date.year", "operator": "equals", "value": 2024}
]
}
)
data = response.json()["data"]
df = pd.DataFrame(data)
# Export to Hyper format for Tableau
pantab.frame_to_hyper(df, "olytix-core_data.hyper", table="orders")
JDBC/ODBC Connection
Connect Tableau directly to your data warehouse, using Olytix Core for metric definitions only.
Hybrid Approach
- Define metrics in Olytix Core
- Export calculated SQL to Tableau
- Use as Custom SQL in Tableau
# Get SQL for a metric
response = requests.post(
"http://localhost:8000/api/v1/query/sql",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"metrics": ["monthly_revenue"],
"dimensions": ["region"],
}
)
sql = response.json()["sql"]
# Use this SQL in Tableau's Custom SQL connection
Tableau Custom SQL
In Tableau, use the generated SQL:
-- Generated by Olytix Core
SELECT
region,
DATE_TRUNC('month', order_date) as order_month,
SUM(total_amount) as monthly_revenue
FROM analytics.fct_orders
WHERE status = 'completed'
GROUP BY 1, 2
Tableau Server/Cloud Integration
Publish Data Sources
Create a shared Olytix Core data source on Tableau Server:
- Create the connection in Tableau Desktop using WDC or Custom SQL
- Publish to Tableau Server: Server > Publish Data Source
- Set refresh schedule for extracts
REST API for Embedding
Use Tableau's REST API with Olytix Core data:
import tableauserverclient as TSC
# Authenticate to Tableau Server
tableau_auth = TSC.TableauAuth('username', 'password', 'site_id')
server = TSC.Server('https://tableau.example.com')
with server.auth.sign_in(tableau_auth):
# Get workbook
workbook = server.workbooks.get_by_id('workbook_id')
# Trigger extract refresh (which pulls from Olytix Core)
server.workbooks.refresh(workbook)
Calculated Fields with Olytix Core Metrics
When using Olytix Core metrics in Tableau, maintain consistency with calculated fields:
Metric Definitions
Document your Olytix Core metrics for Tableau users:
| Olytix Core Metric | Tableau Field | Calculation |
|---|---|---|
total_revenue | [Total Revenue] | SUM([Amount]) |
order_count | [Order Count] | COUNT([Order ID]) |
avg_order_value | [Avg Order Value] | [Total Revenue]/[Order Count] |
Parameter-Based Filtering
Use Tableau parameters with Olytix Core filters:
# Dynamic query based on Tableau parameter
def query_olytix-core_with_filter(region_filter):
return requests.post(
"http://localhost:8000/api/v1/query",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"metrics": ["total_revenue"],
"dimensions": ["product_category"],
"filters": [
{"dimension": "region", "operator": "equals", "value": region_filter}
]
}
).json()
Performance Optimization
Extract Scheduling
For large datasets, use scheduled extracts:
# Extract configuration
extract_schedule:
frequency: daily
time: "02:00"
timezone: "America/New_York"
queries:
- name: orders_daily
metrics: [total_revenue, order_count, avg_order_value]
dimensions: [region, product_category, order_date.day]
filters:
- dimension: order_date
operator: gte
value: "{{ today - 365 }}"
Pre-aggregation Alignment
Align Olytix Core pre-aggregations with Tableau usage patterns:
# cubes/orders.yml
pre_aggregations:
- name: tableau_daily
measures: [total_revenue, order_count]
dimensions: [region, product_category]
time_dimension: order_date
granularity: day
refresh_key:
every: "1 hour"
Connection Pooling
For high-concurrency Tableau Server:
# Olytix Core API configuration
api:
connection_pool:
min_size: 10
max_size: 50
rate_limit:
requests_per_minute: 1000
Security Configuration
Row-Level Security
Pass Tableau user context to Olytix Core for RLS:
# In WDC or custom integration
def get_tableau_user_context():
return {
"user_id": tableau.username,
"user_email": tableau.useremail,
"groups": tableau.usergroups
}
# Pass to Olytix Core
response = requests.post(
"http://localhost:8000/api/v1/query",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"X-Olytix Core-User-Context": json.dumps(get_tableau_user_context())
},
json=query
)
API Key Management
Use separate API keys for different Tableau workbooks:
# Olytix Core security configuration
api_keys:
- name: tableau_sales_dashboard
key: ${TABLEAU_SALES_API_KEY}
permissions:
cubes: [orders, customers]
- name: tableau_marketing_dashboard
key: ${TABLEAU_MARKETING_API_KEY}
permissions:
cubes: [campaigns, leads]
Troubleshooting
Connection Timeout
Error: Connection to Olytix Core timed out
Solutions:
- Increase timeout in WDC configuration
- Check network connectivity between Tableau and Olytix Core
- Verify Olytix Core API server is running
Data Type Mismatch
Error: Cannot convert value to expected type
Solutions:
- Map Olytix Core types correctly in WDC
- Use explicit type casting in Custom SQL
- Verify dimension types in cube definition
Authentication Failed
Error: 401 Unauthorized
Solutions:
- Verify API key is correct
- Check API key permissions
- Ensure key hasn't expired
Large Dataset Performance
Solutions:
- Use extracts instead of live connections
- Enable Olytix Core pre-aggregations
- Add filters to reduce data volume
- Increase Olytix Core query timeout
Best Practices
- Use Pre-aggregations: Align Olytix Core pre-aggs with common Tableau queries
- Standardize Naming: Use consistent naming between Olytix Core and Tableau
- Document Metrics: Maintain metric glossary for Tableau users
- Version Control: Track Tableau workbook versions alongside Olytix Core models
- Test Changes: Validate Olytix Core changes don't break Tableau dashboards