Skip to main content

Dynamic Data Sources & Schemas for Embedded Analytics

Coming Soon

This feature is under active development and will be coming soon!

Introduction

dynamic data source embed

When implementing embedded analytics, you may have customers with their own separate databases (or schemas). In this case, you'll want to configure your embedded dashboard to dynamically connect to the appropriate database based on which user is viewing it.

This post explains how to do that using our Dynamic Data Sources mechanism.

Use Case: Dynamic Data Source

1. Connect databases

First, make sure you connect all databases of your customers to Holistics.

The data source name will be used to identify which database to connect to at later steps, so you should use a unique and meaningful name for each data source.

2. Create a data_source variable in your AML codes

Go to the Development tab, create a new file embedded_variables.aml and add the following code:

const client_data_source = create_slot<String>({
path: 'H.embed.attributes.data_source'
})

Tip: you can name the file anything you want, as long as it ends with .aml.

3. Modify the embedded dashboard's dataset code

Modify the dataset code that powers the embedded dashboard to use this data_source variable:

Dataset dynamic_client_dataset {
label: 'Dynamic Client Dataset'

data_source_name: if (client_data_source) {
client_data_source
} else {
'dev_datasource'
}

models: [ orders ]
relationships: [ ]
}

4. Pass data source name in the backend

When generating the embedded payload on your backend app, you can calculate and pass in the appropriate data source depending on your currently logged-in user.

// Embedded payload
embedded_payload = {
permissions: {},
attributes: {
data_source: 'your_data_source_name'
}
}

Use case: Dynamic Schema

1. Create a schema variable in your AML codes

const client_schema = create_slot<String>({ path: 'H.embed.attributes.schema' })

2. Modify the embedded dashboard's data models

  • For TableModel
Model dynamic_model {
type: 'table'
data_source_name: 'my_wh'
table_name: '${client_schema}.cities'
}
  • For QueryModel
Model dynamic_model {
type: 'query'
data_source_name: 'my_wh'
query: @sql
select *
from ${client_schema}.cities
;;
models: []
}

3. Pass schema name in the backend

// Embedded payload
embedded_payload = {
permissions: {},
attributes: {
schema: 'your_schema_name'
}
}

How it works

The dynamic feature works through a simple two-step process:

  1. First, it creates a variable with a predefined path that acts as a placeholder
  2. Then, when you send a JSON payload to Holistics, the system locates the variable using this path and dynamically replaces it with the actual value from your payload

This allows you to flexibly change data sources/schemas at runtime based on the values you provide.

Supported Paths

  1. H.embed.attributes.*

The H.embed.attributes.* path allows you to define custom attributes that can be dynamically set through the embedded payload. The * represents any valid attribute name of your choice.

Here's an example demonstrating how to use custom attributes for 2 data sources:

First, you create 2 variables:

const client_a_data_source = create_slot<String>({
path: 'H.embed.attributes.client_a_data_source'
})

const client_b_data_source = create_slot<String>({
path: 'H.embed.attributes.client_b_data_source'
})

Then, you pass those values in the embedded payload:

embedded_payload = {
permissions: {},
attributes: {
client_a_data_source: 'client_a_data_source',
client_b_data_source: 'client_b_data_source'
}
}

  1. H.embed.is_embedded

This is a built-in variable that will be true if the dashboard is viewed in the embedded mode, and false if it's not. This is useful when you want to test this dashboard in your Development environment.

Example:

const is_embedded = create_slot<Boolean>({ path: 'H.embed.is_embedded' })
const client_data_source = create_slot<String>({ path: 'H.embed.attributes.data_source' })

const data_source_name = if (is_embedded) {
client_data_source
} else {
'dev_datasource'
}

Supported Data Types

Currently, you can pass these JSON data types in the embedded payload:

JSON TypeHolistics Type
stringString
booleanBoolean
numberNumber
array🛠️ To be supported soon

Advanced example

const dynamic_data_source = create_slot<String>({
path: 'H.embed.attributes.data_source'
})

const dynamic_schema = create_slot<String>({
path: 'H.embed.attributes.schema'
})

const is_embedded = create_slot<String>({ path: 'H.embed.is_embedded' })

// Define a custom type to group data source and schema into a single object for easier access
Type DynamicSource {
data_source: Slot<String>
schema: Slot<String>
}

DynamicSource dynamic_source {
data_source: if (is_embedded) { dynamic_data_source } else { 'dev_datasource' }
schema: if (is_embedded) { dynamic_schema } else { 'dev_schema' }
}

// In a Dataset
Dataset dynamic_dataset {
data_source_name: dynamic_source.data_source // dynamic data source
// ...omit for brevity
}

// In a TableModel
Model dynamic_model {
type: 'table'
data_source_name: dynamic_source.data_source // dynamic data source
table_name: '${dynamic_source.schema}.orders' // dynamic schema
// ...omit for brevity
}

Let us know what you think about this document :)