# Welcome to Whaly 🐳

[Whaly](https://whaly.io) 🐳 is a self service business intelligence platform that helps data analysts deliver faster insights to business teams, and helps business teams to get access to data so they can take better decisions.

This documentation is geared towards data analysts so they are able to manage and roll out [Whaly](https://whaly.io) in their organisation. In this guide you'll learn how to:<br>

1. [**📦 Connect to your data Warehouse**  <br>](/warehouse/connect-your-warehouse)Whaly is directly connected to your Data Warehouse ([BigQuery](/warehouse/google-bigquery) / [Snowflake](/warehouse/snowflake)) so that your data stays in your control, from the ingestion to the consumption.<br>
2. [**🔌 Connect business data using Sources**<br>](/connectors/how-sources-work)Whaly connects directly to your key data sources (CRM, Marketing platform, ...) and continuously sync your data into your warehouse so you can create better experiences for your end users.<br>
3. [**🛠 Model your data using the Workbench**](/data-management/workbench)\
   By giving you access to a no code data cleaning and enriching tool, it helps you shape your data to make great reporting.<br>
4. **👀 Create Data Experiences using Explorations**\
   By helping you to create dimensions and metrics on top of all your related data, it make your data "reporting ready".<br>
5. **📈 Get insights by creating stunning Visualizations**\
   By creating reports and dashboards, you'll build visual representation of your data that can be shared to your stakeholders.<br>
6. **🚀 Use your data outside Whaly**\
   Integrate Whaly in your everyday Workflow, whether it is updating a GSheet, an Excel File or an Airtable or even integrating your stunning dashboards in your own product or even your business apps, you'll learn how to achieve exactly that.<br>
7. 📜 **Achieve high scale governance with Whaly**\
   You'll learn how to use Whaly access control layer to control, and optimize who has access to which type of data.<br>


# What is a team?

A team is the group of all the users of your company. This is where you can see  who from your organization has created a Whaly account.

Inside your team, you can share multiple [Organization](/organisation/what-is-an-organisation) to collaborate on Business Intelligence projects.

Member of a team can have 2 main roles:

* **Owner**: It means that you have access on the team management page, where you can review all Team Members, [Organizations](/organisation/what-is-an-organisation) and configure the team security settings such as enabling Single Sign On
* **Regular member**: You are part of the team and can be invited into each Organization of the team is needed but you don't have any power on the team structure

### Managing the Team

For all **Team Owners**, a **Manage** button is available on the [Organization](/organisation/what-is-an-organisation) selector screen ⤵️

<figure><img src="/files/92yc2CcmtiJIlAW8NZ3b" alt=""><figcaption><p>Position of the Manage button to access Team Management page</p></figcaption></figure>

When clicked, the link is redirecting you to the Team Management page ⤵️

<figure><img src="/files/pH6xuFZN6GHnynJlujs3" alt=""><figcaption></figcaption></figure>

From this page, you can manage:

1. Your Single Sign On configuration
2. The [Organizations](/organisation/what-is-an-organisation) that are being used by members of your Team
3. The list of all members of your team and their roles (Owner vs Regular Member)


# Single Sign On

Whaly supports Single Sign On. This means that you can plug your existing Identity Provider such as Google Workspace, Microsoft Azure Directory, Okta, custom SAML ... into Whaly so that your Team Member have to login through your company identity system before accessing Whaly.

This offers multiple advantages:

* When your IT team disable a User in your company directory, the User no longer can access Whaly
* Your IT team can decide form your Directory which User should have access to Whaly or not
* Your Team Members passwords are never known / saved into Whaly systems
* Whaly will create users "on the fly" when they first login. This means that you don't have to create any Whaly access for your new team members or invite your whole company before they can get access

Overall, enabling Single Sign On is:

* More secure
* Give you more control
* Lower the user management cost for your IT Team
* Offer a better login experience to your Team Members
* In many case, this is required if your company is security certified (SOC2 / ISO27001)

In order to configure your SSO, you simply have to go to your [Team Management](/team/what-is-a-team#managing-the-team) page and click on "Configure my SSO". You'll be redirected to a portal where you can self configure your SSO Provider.

{% hint style="info" %}
If your current plan doesn't include SSO support, a link to contact Whaly Sales team will be displayed so that you can discuss about your needs.
{% endhint %}

### User provisioning

Whenever a new User from your company directory is logging for the first time into Whaly, a new User will be created on the fly and a Viewer (free) access will be created on the Organizations of your team.

The Administrators of your [Organizations](/organisation/what-is-an-organisation) will then be able to assign the proper [access](/organisation/manage-access-control) and [licenses](/organisation/understanding-licences) to them.

## Supported Identity Providers

Whaly currently supports the following Identity Providers:

<figure><img src="/files/ptOU81kdEnTvchjAmvkA" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Thanks to our generic SAML support, we can also connect to Identity providers that are not included in the list.

Contact your support if you need assistance!
{% endhint %}


# Impersonate

When building your system of permissions, it can get tricky to know what can each of your users view and access or reproduce some access control issues that could block them.

To help **Team Owners** configure and troubleshoot the access control settings of their [Team users](/team/what-is-a-team), an **Impersonate** functionality is available in the [Access Management settings page](/organisation/manage-access-to-your-organisation) of each organisation.

{% hint style="info" %}
For security reasons, **only the Team Owners** has access to this Impersonate functionality. Regular Users of the Team can't impersonate each others.
{% endhint %}

<figure><img src="/files/7Lq8jM1JQeRMGR9CY0cx" alt=""><figcaption></figcaption></figure>

When clicking on the **Impersonate** button, you are automatically redirected to the Organization picker as if you were the Impersonating user. You have the same level of access that they have and any actions done in their name will be accounted for the Impersonated User.

A message at the top of the screen will remind you at all time that you are not using your own account but rather using the one of the Impersonated User.

<figure><img src="/files/xsDjD4Yld2XpkgE4GNEp" alt=""><figcaption></figcaption></figure>


# What is an organisation?

An organization is a home for all content that will be created on Whaly, imagine it as a library where all your content is stored.

An organization is plugged on a Warehouse where your data lives. It'll store all your models, sources, dashboards, questions...

You can have access to multiple organizations for different purposes:

* When you want to have multiple different Warehouse
* When you want to have a "Training Sandbox" to test a few things without ta
* For testing purposes of new features
* If you're invited by another company to collaborate on their environment&#x20;

### How to switch between organization?

If you have access to multiple orgs you can switch org by clicking on your **profile picture** and then on  **Change Organization**.

<figure><img src="/files/6sY7Oo2hBNXKre5GylzR" alt=""><figcaption><p>Switch org</p></figcaption></figure>


# Upload your Organisation logo

Admins can go to the Organisation settings in order to uploads your organisation logo. This is useful to:

* Improve the brand identity coherence
* Makes end users feels like home

<figure><img src="/files/XArKZNqPmiTUkPw94Z5y" alt=""><figcaption></figcaption></figure>


# Manage Access to your organisation

You can manage who has access to your org by going to the **settings page** and then to the **access management** page

<figure><img src="/files/T7UbF0NMXu4PiSXQqZCt" alt=""><figcaption><p>Settings</p></figcaption></figure>

On the access management page you can view all the users that have access to your org including Whaly Staff user that have access to your org for support purposes.

<figure><img src="/files/yh9ez3RifEKwrch8k1LK" alt=""><figcaption></figcaption></figure>

You can differentiate Whaly support team from your users by the **Whaly support team** tag as you can see above.&#x20;

{% hint style="info" %}
Note that you won't be billed for the **Whaly support team** user access as we assign them a viewer licence which are forever free.
{% endhint %}

### Granting access to your org

<figure><img src="/files/KYB9uPqMVgGOx5N0a32I" alt=""><figcaption><p>Access management page</p></figcaption></figure>

You can grant access to anybody in your org by simply inviting them. In order to do so you can click on the **invite button** and fill the form to invite your user.&#x20;

<figure><img src="/files/aLnMJvn0Ns3kuAhT1as1" alt=""><figcaption></figcaption></figure>

When inviting a user you are asked to select a user role for your invited user. In order to understand what each role can do on the platform and how they are correlated to licensing you can check those articles.

{% content-ref url="/pages/dkDUWrVHSygQsO9snp3w" %}
[Understanding Licences](/organisation/understanding-licences)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg5ic4nGm150muQZk-u" %}
[Understanding User Roles](/organisation/manage-access-control)
{% endcontent-ref %}

Once this is done you'll see the invite appear in the access view.&#x20;

<figure><img src="/files/N95rKQO7WNvFbfqvqiaC" alt=""><figcaption><p>Editing an invite</p></figcaption></figure>

If your user has not received the invitation email you can check in their spam folder or send them directly the link to the invitation by clicking on the three dots and then **Copy invite link.** You can also **revoke** the invitation if needed.

Once a user has accepted your invitation they will appear in the list as a regular user.

### Changing access to your org

{% hint style="info" %}
You can remove **Whaly support team** from your org so your keep things more private
{% endhint %}

<figure><img src="/files/Ceiav1EMo9Ply3NDnF6h" alt=""><figcaption></figcaption></figure>

You can remove at any time any users from your org by simply clicking on the three little dot next to a user that has accepted the invitation. From there you can either delete the user from your org or change it's user role.


# Understanding Licences

Licences are attached to all your org users. There are three types of Licences:

### Builder Licence

Builder licence are usually given to member of the data team that will model data and configure Whaly for other user to consume data out of it. This licence is tied with workbench access in edition mode.

**User role associated**

* [Admin Builder](/organisation/manage-access-control#admin-builder)
* [Builder](/organisation/manage-access-control#builder)

### Standard Licence

Standard Licence are given to power business users that are capable of asking question through exploration and that are capable of creating dashboard. This licence is tied to dashboard creation.&#x20;

**User role associated**

* [Editor](/organisation/manage-access-control#editor)

### Viewer Licence

Viewer Licence are forever free and will be given to any member of your company or people you interract with.

**User role associated**

* [Report viewer](/organisation/manage-access-control#report-viewer)
* [Viewer](/organisation/manage-access-control#viewer)


# Understanding User Roles

This page explain you how you can manage which user of your org can have different rights on Whaly.

### User Roles

There are four different user roles in [Whaly](https://whaly.io).

#### Admin Builder

An admin builder can view / edit / delete everything. Meaning that he has the ability to:

| object       | right                            |                                                                                                                                |
| ------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Users Invite | Read / Create                    | An **admin builder** can invite whoever he wants in the org and give them the appropriate role                                 |
| User Roles   | Read / Create / Update / Delete  | An **admin builder** can change any user role to the role he judges the most appropriate                                       |
| Sources      | Read / Connect / Update / Delete | An **admin builder** can connect any source to its org and remove sources that were previously connected or change the config. |
| Explorations | Read / Create / Update / Delete  | An **admin builder** can create, read, modify and remove any exploration                                                       |
| Workbench    | Read / Create / Update / Delete  | An **admin builder** can access the workbench, create, remove columns and add formulas, rollups, and lookups                   |
| Reports      | Read / Create / Update / Delete  | An **admin builder** can create, read, modify and remove any reports                                                           |

#### Builder

A builder has essentially the same rights as an owner except for user management.&#x20;

| object       | right                            |                                                                                                                         |
| ------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Users Invite | Read                             | A **builder** can view invitations but cannot invite a user.                                                            |
| User Roles   | Read                             | A **builder** can view user roles but cannot modify them                                                                |
| Sources      | Read / Connect / Update / Delete | A **builder** can connect any source to its org and remove sources that were previously connected or change the config. |
| Explorations | Read / Create / Update / Delete  | A **builder** can create, read, modify and remove any exploration                                                       |
| Workbench    | Read / Create / Update / Delete  | A **builder** can access the workbench, create, remove columns and add formulas, rollups, and lookups                   |
| Reports      | Read / Create / Update / Delete  | A **builder** can create, read, modify and remove any reports                                                           |

#### **Editor**

An editor can create reports in the org, and has access to explorations and reports. He has the ability to:

| object       | right                           |                                                                                 |
| ------------ | ------------------------------- | ------------------------------------------------------------------------------- |
| Users Invite | Read                            | An **editor** can view invitations but cannot invite a user.                    |
| User Roles   | Read                            | An **editor** can view user roles but cannot modify them                        |
| Sources      | Read                            | An **editor** can view connected sources but cannot modify them.                |
| Explorations | Read                            | An **editor** can view explorations, can run queries but cannot modify anything |
| Workbench    | No access                       | An **editor** doesn't have access to the workbench                              |
| Reports      | Read / Create / Update / Delete | An **editor** can create, read, modify and remove any reports                   |

#### **Viewer**

A viewer cannot edit anything in the org, but has access to explorations and reports. He has the ability to:

| object       | right     |                                                                                |
| ------------ | --------- | ------------------------------------------------------------------------------ |
| Users Invite | Read      | A **viewer** can view invitations but cannot invite a user.                    |
| User Roles   | Read      | A **viewer** can view user roles but cannot modify them                        |
| Sources      | Read      | A **viewer** can view connected sources but cannot modify them.                |
| Explorations | Read      | A **viewer** can view explorations, can run queries but cannot modify anything |
| Workbench    | no access | A **viewer** doesn't have access to the workbench                              |
| Reports      | Read      | A **viewer** can access reports but cannot modify nor delete them              |

#### **Report Viewer**

A report viewer cannot edit anything in the org, and has only access to reports. He has the ability to:

| object       | right     |                                                                          |
| ------------ | --------- | ------------------------------------------------------------------------ |
| Users Invite | Read      | A **report viewer** can view invitations but cannot invite a user.       |
| User Roles   | Read      | A **report viewer** can view user roles but cannot modify them           |
| Sources      | Read      | A **report viewer** can view connected sources but cannot modify them.   |
| Explorations | No access | A **report viewer** doesn't have access to explorations                  |
| Workbench    | No access | A **report viewer** doesn't have access to the workbench                 |
| Reports      | Read      | A **report viewer** can access reports but cannot modify nor delete them |


# User Attributes

User attributes allow for personalized experiences for Whaly users. These attributes are defined by Whaly administrators and can be applied to individual users.

User attributes can be referenced throughout Whaly to provide a custom experience for each user. Whaly provides several default user attributes including:

* ID
* Email

### Viewing user attributes <a href="#viewing_user_attributes" id="viewing_user_attributes"></a>

To access your user attributes, navigate to the **Access Admin > User Attribute** section of the Setting menu and select the User Attributes page.&#x20;

Here, you will find a table that displays the technical name, label, and type of each user attribute. The table also includes buttons for performing actions related to the user attribute.

### Creating user attributes <a href="#creating_user_attributes" id="creating_user_attributes"></a>

To define a user attribute, click the **Create new Attribute** button at the upper right of the screen. Each user attribute has the following settings:

* **Label**: The user-friendly name of the attribute.
* **Technical Name**: The technical name of the user attribute, that will be used in the API or in CSV users imports.
* **Data Type**: This setting is used to check that valid values are assigned to users for this user attribute. The data type of the user attribute can be one of the following:
  * **String**: Select this option to create a user attribute that exactly matches one or multiple string value, such as a username, tenant ID, ...
  * **Number**: Select this option to specify a single number, such as employee number.
  * **Date**: Select this option to specify a single date or time, such as user's birth date or a max lookback date.
  * **Boolean**: Select this option to set this attribute to be either set as True or False.
* **Allow multiple values**: Select this checkbox to allow users to have multiple values for the attribute. It can be useful if you want some manager to have access to multiple Sales region for example.
* **Allow only specific values**: Select this checkbox to pass the allowlist of authrorized values that can be given for this attribute to user.
* **Set a default value**: Select this checkbox to set a default value in case a value is not assigned to a user.

<figure><img src="/files/EbNy0qfWDFcVDmcuwz8f" alt=""><figcaption></figcaption></figure>

### Assigning values to individual users <a href="#assigning_values_to_individual_users" id="assigning_values_to_individual_users"></a>

After defining a user attribute, you can assign a value for it to an individual user:

1. Go to the Settings > Access Admin > **Access Management** page.
2. Choose the user to assign a value and click on "Edit User"
3. In the Attributes section, enter the new value in the proper field.
4. Click **Save**.

<figure><img src="/files/aOiBC7zyppx1IG8IdPIl" alt=""><figcaption></figcaption></figure>

### Where can user attributes be used? <a href="#where_can_user_attributes_be_used" id="where_can_user_attributes_be_used"></a>

#### Reports Filters

Filters on reports can be set to a user attribute to customize the query based on the user who is running it.

For example, you could configure a user attributes named "salesforce\_username" and customize it for every Whaly user by entering their Salesforce username as its value. By setting a filter on a dashboard using the "salesforce\_username" user attribute, each user would be able to view the dashboard with data filtered according to their particular Salesforce username.


# User Groups

User Groups are a set of Users that share the same access over a set of dashboards & questions. Properly defining and creating Groups to match your internal organisational structure is key to build a manageable Access Control setup and make sure that everyone has access only to the proper ressources.

### Default User Groups

By default, 2 User Groups are created and automatically managed by Whaly:

* **All Users**: This group contains all the users having an access on your Organisation. This group is really handful to give access to "Company wide" dashboards and questions.
* **Admins**: This group contains only the users having an admin access on your Organisation. This group will have access by default to all the content created on your Organisation so that they can administrate it properly.

### Listing all existing groups

In order to list all the existing User Groups in your Organisation, please go in "**Settings > Groups**" page. There, you'll see the list of existing User Groups.

<figure><img src="/files/yhA1H8Qh6z0PlJnKMFqx" alt=""><figcaption></figcaption></figure>

1. You can click here to create a new User Group
2. You can edit or delete existing User Groups
3. You can see all the existing User Groups

### Creating a group

By clicking on "**Create new Group**" button, you'll open a screen where you can fill:

a. The name of the created Group

b. The list of the Organisation's Users that you want to add to the Groups

{% hint style="info" %}
Only Users that have already been invited and that created their account on Whaly will be available in the list. If you wish to add a User that hasn't got access to your Whaly organisation yet, please invite them first.
{% endhint %}

<figure><img src="/files/FaSqPa3GKFJJPnjUFvvF" alt=""><figcaption></figcaption></figure>

1. Give your Group the proper name
2. Add the relevant users
3. Save the group

### Adding/Remove users in a group

You can click on the \`...\` icon of any existing Group and select "**Edit**" to open the screen where you can add or remove any User from an existing group.

<figure><img src="/files/ATPKKRnItummUcL4kffd" alt=""><figcaption></figcaption></figure>

1. Add new Users
2. Remove existing Users
3. Save the changes


# Service Accounts

Service accounts are technical users used to authenticate API integrations between Whaly and external systems and applications.

## Service Account Documentation

### Introduction

Service accounts are technical users used to authenticate API integrations between Whaly and external systems and applications. They provide a secure way to access Whaly APIs without relying on individual user credentials. This documentation aims to provide an overview of how to use Whaly service accounts, their purpose, benefits, and guidelines for managing and using them effectively.

Unlike user accounts, service accounts are not associated with individual users and do not have interactive login capabilities. They are designed to perform automated tasks in Whaly (create User Accounts on the fly, download data, etc.) to bridge your internal systems with Whaly.

### 1. Purpose and Benefits

The use of service accounts offers several advantages:

* **Secure Authentication:** Service accounts provide a secure method for authenticating API requests through Keys without exposing user credentials or relying on manual authentication steps.
* **Resilient to Users updates**: People join and leave your organization all the time. Linking an integration to a User account create the risk that the integration can break whenever the linked User account change its permissions or is disabled. By relying on Service Accounts instead, your integrations are less encline to break.
* **Granular Control:** Service accounts can be granted specific roles and access controls, allowing fine-grained control over the actions they can perform on Whaly APIs.
* **Auditability:** Service accounts enable logging and auditing of API requests and tie them with the Service Account name, providing an audit trail for monitoring and troubleshooting purposes.

### 2. Creating a Service Account

In order to create a Service Account, you have to go to the Service Account panel in the Settings of your organization.

<figure><img src="/files/Lh6bPYjuC0Yo02ae4miv" alt=""><figcaption></figcaption></figure>

From this screen, you can see the already existing Service Accounts and create new ones to authenticate a new Integration. You have to click on the "Create Service Account" button to do that.

<figure><img src="/files/4s5pWeJ3LEM67yScddng" alt=""><figcaption></figcaption></figure>

In the panel that appears, you can:

* Give the proper name to the Service Account so you identify it and how it's being used later one when reviewing your open access. Make sure to use a descriptive name.
* The Role that this Service Account should have on your Organization. This will impact the API that the Service Account will be able to access.

Once it's done, you can click on "Submit" to create the Service Account.

<figure><img src="/files/Sku3OeAWSIUgWQYzNlL6" alt=""><figcaption></figcaption></figure>

When creating a new Service Account, a Key is automatically attached to it and you can copy paste the associated API Token that will be used to authenticate as this Service Account through the API.

{% hint style="info" %}
The value of the API Token is only available on the Key creation time, so be sure to cpy and store in a safe place its value because it won't be available in Whaly interface after that.

If you lose the API Token, you can always create a new Key on the existing Service Account to get a fresh API TOken.
{% endhint %}

### 3. Service Account Keys

Each Service Account can hold many Keys. Those Keys are attached to a API Token that is the value to be used when authenticating against the API.

In order to manage Keys, you can click on the "..." icon on a Service Account row and click on "Manage Keys".

<figure><img src="/files/hb11NTypyBekWFMkIJBP" alt=""><figcaption></figcaption></figure>

From this screen, you can list the already existing keys, view an obfuscated value of their API Token and either remove existing Keys or create new ones.

### 4. Best Practices for Service Account Management

To ensure effective management and security of your service accounts, consider the following best practices:

* **Naming Conventions:** Establish a consistent naming convention for each service accounts, enabling easy identification and categorization based on their purpose and associated systems.
* **Regular Review and Maintenance:** Perform regular reviews of existing service accounts and their Keays to ensure they are still required and have appropriate permissions. Remove or revoke unnecessary or unused service accounts promptly.
* **Rotation of Keys:** Implement a regular rotation policy for service account keys to mitigate the risk of compromised credentials.
* **Least Privilege Principle:** Adhere to the principle of least privilege when granting permissions to service accounts. Only assign the minimum necessary permissions required for their intended functionality, reducing the potential impact of a compromised service account.
* **Documentation and Ownership:** Maintain accurate documentation of service accounts, including their purpose, associated systems or applications, and responsible owners. This documentation ensures clear accountability and facilitates efficient management.

<br>


# Workspace

<figure><img src="/files/pNGODh1n9tVUX0V1StTx" alt=""><figcaption><p>Example of a workspace</p></figcaption></figure>

The workspace is what you access when you want to consume content from Whaly. The workspace is comprised of three main areas from the left to the right:

## **Tab Selector (1)**

Help you switch from the workspace to our catalog and the settings

{% content-ref url="/pages/icFDN7pHh1inCJIL7RFB" %}
[Catalog](/workspace/catalog)
{% endcontent-ref %}

{% content-ref url="/pages/fMRrN6DhQVCaljhO7VT8" %}
[Settings](/workspace/settings)
{% endcontent-ref %}

## **Content Selector (2)**

Help you switch between folders, explorations and the workbench

{% content-ref url="/pages/sLe4nWeIRANLAHX2k7Mr" %}
[Explorations Section](/content-management/explorations-section)
{% endcontent-ref %}

{% content-ref url="/pages/mVUtGHekrQCD9klQ5KOa" %}
[Report Folders](/workspace/report-folders)
{% endcontent-ref %}

{% content-ref url="/pages/-M\_11vF4qsUeLTDz8nkr" %}
[Modeling](/data-management/workbench)
{% endcontent-ref %}

{% content-ref url="/pages/1HcpAdFZQt7OXanRwF65" %}
[Source monitoring](/connectors/source-monitoring)
{% endcontent-ref %}

## **Content Viewer (3)**

Help you find content inside a folder

{% content-ref url="/pages/rw4wDokjYz2zFjzp5FD3" %}
[Dashboards](/data-consumption/dashboards)
{% endcontent-ref %}

{% content-ref url="/pages/XLekAAyr3zhomQDHoFmK" %}
[Questions](/data-consumption/questions)
{% endcontent-ref %}


# Report Folders

## What is a Report Folder

A folder helps you organize your dashboards and questions into a comprehensive manner that makes sense for your company.

## Create a Report Folder

<figure><img src="/files/gwq3q1ZgwMRj73YGxUfC" alt=""><figcaption><p>Creating a folder</p></figcaption></figure>

In order to create a report folder click on the + button next to workspace or next to the folder and then give it a name and an icon and voila you are all set !

## Move a Report Folder

You can move folder around to change your company folder structure, this will update to all users in real time.

<figure><img src="/files/0eSh1umcHWDDZSLq4Izb" alt=""><figcaption><p>Moving a folder</p></figcaption></figure>

## Update / Delete a Report Folder

By clicking on the three dots next to a folder's name you can update or delete a folder.

<figure><img src="/files/Lv3xeCnxs3koW3BzBSak" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
When deleting a folder this also deletes the dashboards and questions that are stored inside&#x20;
{% endhint %}


# Sharing & Collaboration

Whaly is built to be super collaborative, so there's a number of ways to share the dashboards you create with other people, exactly the way you want them to.

## Ways to share

There are several different ways you can share the reports you build in Whaly with folks inside and outside your organisation. Below is an overview of all the ways to share.

In order to manage the visibility and sharing of Reports inside Whaly, you'll have to use the Sharing configuration of the **Folders** where the Reports are stored.

{% hint style="info" %}
**All Reports stored in the same Report Folder** will be shared to the **same audience** in the same way, so if you want to have different Sharing settings for different Reports, you will have to **create different Folders** for those.
{% endhint %}

#### Share menu <a href="#share-menu" id="share-menu"></a>

First, here's a quick tour of the `Share` menu, which can be clicked when opening the `...` menu of your Report Folder.

<figure><img src="/files/7pCFRJ7R2KEVtDtFF2A6" alt=""><figcaption><p>Share button is in the <code>...</code> menu of Report Folders</p></figcaption></figure>

<figure><img src="/files/HuPHTRbZG1YBPFblBcuo" alt=""><figcaption><p>The Share menu shows who can currently access the folder and gives control to update the sharing configuration</p></figcaption></figure>

* Each row in this menu represents a different person or group of people you can share the Folder with. In the menu above for this 'My Folder' report folder:
  * `Admins`  means that the Admins in your workspace has full access on the report. They'll be able to make edits and invite additional people.
  * `Engineering` means that all the members of the Engineering group has full access on the report. They'll be able to make edits and invite additional people.
  * `All Users` means that all members of the organization will have a read only access on the folder and its Reports.
  * `Emilien` is an exemple of a team member with only edits right on the folder. He will be able to edit the folder name and position in the folder hierarchy and edit all Reports in the folder but won't be able to change its sharing configuration.
* `Invite` lets you add people/groups inside your organization to this folder using their email address/name
  * You will be able to select the access they should have on this report

<figure><img src="/files/OR33kneWT25zC0jE4zst" alt=""><figcaption><p>When inviting someone to collaborate on a folder, a permission level can be assigned to control its access</p></figcaption></figure>

#### Share with everyone in your workspace <a href="#share-with-everyone-in-your-workspace" id="share-with-everyone-in-your-workspace"></a>

You can collaborate with other people in Whaly by adding them as users to your workspace. These can be your teammates at work, partners, or anyone you want to work with on Reports. You can share Whaly reports with all members of your organizatrion so you can work together:

* In the `Share` menu, you can turn on access for `All Users` at a certain level selected from the dropdown

<figure><img src="/files/mhMxkwTgXUAmkUAwbKNu" alt=""><figcaption></figcaption></figure>

#### Share with individual teammates <a href="#share-with-individual-teammates" id="share-with-individual-teammates"></a>

Sometimes you'll want to share a folder with only select other members of your organization — like a personal objective tracking dashboard you share with your manager.

* Click `Share` in a Report Folder menu.
* Click the `Add emails or people` search bar and add the members you want by typing in their name or email addresses. You can set their access levels from the dropdown at the right side of the search bar.

<figure><img src="/files/7PGZRPUWoodzQUs9GYw3" alt=""><figcaption></figcaption></figure>

#### Share with groups <a href="#share-with-groups" id="share-with-groups"></a>

To make it easier to share with commonly-used groups (i.e. your company's engineering team or sales team), you can create your own member groups and assign them permission to access reports as units.

[Learn more about groups here →](/user-management/user-groups)

**Here are quick instructions for group sharing:**

* Go to `Settings > User Groups` and you'll see a list of all your already existing groups.
* Click `Create new group`, give it a name, and add the members you want
* To share a report folder with a particular group, go to `Share` in the `...` menu of this folder, then click the `Invite` button. You'll see your groups listed in the invite pop-up that appears.

<figure><img src="/files/ssErxQZ5UsKNh6xCHOQH" alt=""><figcaption></figcaption></figure>

#### Share to the web <a href="#share-to-the-web" id="share-to-the-web"></a>

To make a Whaly report viewable as a site on the web or to share it with people who don't use Whaly, you can create a **Sharing Link** directly on a Report you want to share. Anyone with the link will be able to see it.

[Learn more about **Sharing Links** here →](/workspace/sharing-and-collaboration/share-a-report-by-link)

### Permission levels

This is where Whaly's sharing options get nuanced and granular. For every person or group you share with, you can assign a different level of access. **For example**, **this is helpful if:**

* You want only a few people to edit reports, while everyone else reads it.
* You want some reports to only be visible to a specific team.

{% hint style="info" %}
**Note:** When you invite someone to a Report Folder, they can automatically access all of its sub-folders by default. That being said, you can expand sub-folder permissions!
{% endhint %}

#### How to edit permissions <a href="#how-to-edit-permissions" id="how-to-edit-permissions"></a>

Whenever you invite someone to a Report Folder, or click on `Share`, you'll see right-hand dropdown menus next to people or groups that let you select their level of access: `Full access`, `Can edit`, and `Can view`.

* `Full access`: People with full access to a folder can edit any of the content it contains and share the folder with anyone they want using all the mechanisms in this guide.
* `Can edit`: Select this level of access for people or groups who should be able to edit the content on the folder, but not share the folder.
* `Can view`: People with this level of access can read the content on the folder, but not comment on it or edit it. They also can't share the folder with others.

<figure><img src="/files/dKwOyZXckneGLokDfFjv" alt=""><figcaption></figcaption></figure>

#### Stop sharing <a href="#stop-sharing" id="stop-sharing"></a>

If you have full access to a folder, you can disable sharing with anyone at any time.

* Click on `Share` in the `...` menu of the of the folder, and switch off access for your workspace, individuals, groups, or the public. You can also select `Remove` from the dropdown next to any of these.

<figure><img src="/files/EMHDK49RABz0jHQBERK0" alt=""><figcaption></figcaption></figure>

## FAQs

### I want to share a Report with a client, but they don't use Whaly.

You can create a [Sharing Link](/workspace/sharing-and-collaboration/share-a-report-by-link), and share the URL with them. They'll be able to view the report, even if they don't have a Whaly account. However, they won't be able to make any edits.


# Share a report to the Web

Whaly offers 2 ways of sharing a report:

1. Sharing Link
2. Public Link (deprecated)

## Sharing Link

A Sharing Link is a link that can be accessed by anyone even those not having a Whaly account. It's perfect for partners, investors, TV in your offices, etc.

A Sharing Link can:

* 🔐 Be password protected to make sure your data is secured
* 🔎 Contains a set of pre-defined filters to restrict access

A single report can have multiple Sharing Link with different passwords and pre-defined filters for each audience. This way you can share a single dashboard to hundred of different stakeholders.

To create a **Sharing Link**, click on "share" on the top right corner of a Report.

<figure><img src="/files/a1IbaKZtqS92tWFWWIEH" alt=""><figcaption></figcaption></figure>

On the panel that open, you can view all the already existing **Sharing Links**, edit them or get their link.

At the bottom of the panel, you can click on "**New Sharing Link**" to create a new sharing link.

![](/files/0QZboKWwM7cRrqXCqJ1h)

## Public Link (⚠️ deprecated)

A Public Link is generating an URL that gives access to the report to all people loading it. A Report can only have a single Public Link.

{% hint style="warning" %}
Public Link were deprecated in February 2022.&#x20;

You should use a Sharing Link instead as Sharing Link gives you more flexibility and security (filters, password, multiple).

Existing Public Link will continue to work but it'll soon be impossible to generate new ones.
{% endhint %}

### Create a Public Link

* Open a report and in the top right corner, click on "**share**"

![](/files/-Mi8ou9D6VExK6xRwjMg)

2\. Enable the Link Sharing by switching the toggle

3\. Click on "**Get link**"

![](/files/-Mi8p8xS_cpulVy3kdhk)

4\. And Voila! you have the Public Report Link in your clipboard, you can paste it anywhere you need (Slack, Email, [**Whaly Chrome Extension**](/embedding/embed-in-business-apps/google-chrome/configure-the-chrome-extension), ...)


# Catalog

<figure><img src="/files/4IIhR7xv9MIccby34ubX" alt=""><figcaption><p>Whaly Catalog</p></figcaption></figure>

The catalog page allow you to browse our Sources, Warehouses and Actions catalog. You can find a details on each section in the link below:

{% content-ref url="/pages/RRBOZNes1cZuEsafnOv7" %}
[Source catalog](/connectors/source-catalog)
{% endcontent-ref %}

{% content-ref url="/pages/8KNRpJin9FppLoFAiNDB" %}
[Actions catalog](/workflows/actions-catalog)
{% endcontent-ref %}

{% content-ref url="/pages/uQAT2fQUDeasmHIjL4IY" %}
[Connect your Warehouse](/warehouse/connect-your-warehouse)
{% endcontent-ref %}

{% content-ref url="/pages/IcsbLgTuG0msdgldncJF" %}
[Exploration Templates](/data-management/explorations/exploration-templates)
{% endcontent-ref %}


# Settings

<figure><img src="/files/MiLOdkNKJNw1rNISfAzB" alt=""><figcaption><p>Settings</p></figcaption></figure>

## General Settings (1)

From this tab you can:

* view your org name and change it
* view your org slug and change it - the slug is what appears in the URL `https://app.whaly.io/<SLUG>/...`
* view your [client secret for embedding](/embedding/embedding-api)

## Access Management (2)

{% content-ref url="/pages/5iPaJMjY29vaIm9ZtB3O" %}
[Manage Access to your organisation](/organisation/manage-access-to-your-organisation)
{% endcontent-ref %}

## Source Usage (3)

This gives you access to a dashboard to view your consumption from a source perspective

## Warehouse (4)

This tab allow you to view / edit your warehouse credentials, only [Admin Builder](/organisation/manage-access-control#admin-builder) can view it

<figure><img src="/files/lichaMPJfLmnI6ttIBz9" alt=""><figcaption></figcaption></figure>

## Installed Actions (5)

{% content-ref url="/pages/83X70etEJ4aZHXFRprwh" %}
[Manage Installed Actions](/workflows/manage-installed-actions)
{% endcontent-ref %}

## Push history (6)

{% content-ref url="/pages/K5eSvYqtlgaalEGuJPss" %}
[Manage Push](/workflows/push/manage-push)
{% endcontent-ref %}

## Shared Reports (7)

{% content-ref url="/pages/mvxiKkrrc3Bcg4bSJc2G" %}
[Bulk Content Management](/content-management/bulk-content-management)
{% endcontent-ref %}

## Unused Explorations (8)

{% content-ref url="/pages/mvxiKkrrc3Bcg4bSJc2G" %}
[Bulk Content Management](/content-management/bulk-content-management)
{% endcontent-ref %}


# Connect your Warehouse

## **Why connecting your warehouse to** [**Whaly**](https://whaly.io)**?**

In order to use Whaly you have to connect a database that is commonly called a data warehouse. A data warehouse is **a central repository of information that can be analyzed to make more informed decisions**. Data flows into a data warehouse from transactional systems, relational databases, and other sources, typically on a regular cadence.

Connecting a Whaly to a warehouse ensures:

* Your data is stored on your own premise and that you control what Whaly has access to
* Your data is centralized in one database allowing you to "join" multiple sources
* Your data is observable so you can connect to your own warehouse and see exactly how it is stored

## How is the warehouse connection working?

When connecting Whaly to your warehouse, we ensure that the connection to your warehouse is the most secured based on the driver you are using. As of today Whaly supports two drivers, [BigQuery](/warehouse/google-bigquery) and [Snowflake](/warehouse/snowflake).&#x20;


# Amazon Athena


# Connect your Athena

In order to connect your Athena cluster, Whaly needs some credentials. This guide will details the necessary steps:

1. Create an IAM User and generate an Access Key (+secret)
2. Select your region & work group

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

To connect Athena to Whaly, you need the following:

* An AWS Project
* Admin rights on the AWS Project (to create IAM User, custom policy and a S3 Bucket)
* An S3 bucket on which the query results can be written. [You can create one if needed.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)&#x20;

{% hint style="info" %}
To save cost on the Output Bucket, you can configure [its Bucket Lifecycle rule](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) to delete any file after 1 day as the results won't be used after a query have resolved.&#x20;
{% endhint %}

## Create an IAM User and generate an Access Key (+secret)

To connect to your AWS Athena cluster, Whaly need to have a User and its credentials (Access Key). In order to create such a User, [please follow this guide.](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)

When being asked which permissions and policies the user should have, [please create a custom Policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) that have the following rights:

{% hint style="info" %}
In the Policy definition, you need to fill the ARNs of the S3 buckets that Whaly will have access to.&#x20;

Whaly user needs to access to 2 kinds of S3 buckets:

* Input buckets: Those are the buckets in which you have the data that is being queried by Athena
* A single Output bucket: This is the bucket that Whaly will use to store the query results
  {% endhint %}

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:GetTableMetadata",
                "athena:StartQueryExecution",
                "athena:ListDataCatalogs",
                "athena:GetQueryResults",
                "athena:GetDatabase",
                "athena:GetDataCatalog",
                "athena:ListWorkGroups",
                "athena:ListQueryExecutions",
                "athena:GetWorkGroup",
                "athena:StopQueryExecution",
                "athena:ListEngineVersions",
                "athena:GetQueryResultsStream",
                "athena:ListDatabases",
                "athena:GetQueryExecution",
                "athena:ListTableMetadata",
                "athena:BatchGetQueryExecution"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "glue:GetDatabases",
                "glue:GetDatabase",
                "glue:GetTables",
                "glue:GetTable",
                "glue:GetPartition",
                "glue:GetPartitions",
                "glue:BatchGetPartition"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucketMultipartUploads",
                "s3:PutBucketPublicAccessBlock",
                "s3:AbortMultipartUpload",
                "s3:CreateBucket",
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
            // In this list, you should include the S3 ARNs of both inputs and output buckets
            // Ex:
            // Output bucket
            // "arn:aws:s3:::whaly-athena-output/*",
            // "arn:aws:s3:::whaly-athena-output",
            // Input buckets
            // "arn:aws:s3:::whaly-athena-input",
            // "arn:aws:s3:::whaly-athena-input/*",
            // ...
            ]
        }
    ]
}
```

* Once the IAM User created with the proper policy, [you can create an Access Key](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) under it to retrieve the **Access Key Id** and the **Access Key Secret**.

## Select your region & Workgroup

In order to properly query your Athena data, Whaly needs to know in which region you want to run the compute. It should be one of the [AWS Region](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html) (ex. us-east1). A good practise would be to use the same one as the one you are using when doing SQL Queries in the console:

<figure><img src="/files/1KhiXw1Yz6TsYV5BhzeC" alt=""><figcaption></figcaption></figure>

Also, you'll need to [select an existing work group or create one.](https://docs.aws.amazon.com/athena/latest/ug/workgroups-create-update-delete.html) Inside Whaly, you'll need to pass the name of the Workgroup you wish to use when querying your data with Whaly.


# Amazon Redshift


# Connect your Redshift

Setting up the Redshift destination connector involves setting up Redshift entities (user, grants) through Redshift access, and configuring the Redshift destination connector using Whaly UI.

This page describes the step-by-step process of setting up the Redshift destination connector.

### Step 1: Create a Whaly read only user in Redshift​ <a href="#step-1-set-up-airbyte-specific-entities-in-snowflake" id="step-1-set-up-airbyte-specific-entities-in-snowflake"></a>

To set up the Redshift destination connector, you first need to connect to your Redshift server to run some SQL queries.

```sql
CREATE USER whaly_bi WITH ENCRYPTED PASSWORD 'some_password_here';
GRANT CONNECT ON DATABASE database_name to whaly_bi;
\c database_name

GRANT SELECT ON TABLE information_schema.tables TO looker;
GRANT SELECT ON TABLE information_schema.columns TO looker;

GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO whaly_bi;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whaly_bi;
```

**Password Constraints**\
*(taken from the* [*Redshift ALTER USER documentation*](http://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_USER.html)*)*

* 8 to 64 characters in length.
* Must contain at least one uppercase letter, one lowercase letter, and one number.
* Can use any printable ASCII characters (ASCII code 33 to 126) except `'` (single quote), `"` (double quote), ``\`,``/`,`@\`, or space.

If you're using a schema other than `public`, run this command to grant usage permissions to Whaly:

```sql
GRANT USAGE ON SCHEMA schema_name TO whaly_bi;
```

To make sure that future tables you add to the public schema are also available to the `whaly_bi` user, run these commands:

```sql
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON tables TO whaly_bi;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON sequences TO whaly_bi;
```

Depending on your setup, the preceding commands may need to be altered. If another user or role is creating tables that the `whaly_bi` user needs future permissions for, you must specify a *target* role or user to apply the `whaly_bi` user's permission grants for:

```sql
ALTER DEFAULT PRIVILEGES FOR USER <USER_WHO_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON tables TO whaly_bi;
ALTER DEFAULT PRIVILEGES FOR USER <USER_WHO_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON sequences TO whaly_bi;
-- or
ALTER DEFAULT PRIVILEGES FOR ROLE <ROLE_THAT_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON tables TO whaly_bi;
ALTER DEFAULT PRIVILEGES FOR ROLE <ROLE_THAT_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON sequences TO whaly_bi;
```

See [`ALTER DEFAULT PRIVILEGES`](https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_DEFAULT_PRIVILEGES.html) on Redshift's website for more information.

### Step 2: Set up Redshift as a destination in Whaly <a href="#step-3-set-up-snowflake-as-a-destination-in-airbyte" id="step-3-set-up-snowflake-as-a-destination-in-airbyte"></a>

Navigate to the Whaly UI to set up Redshift as a destination. You can authenticate using username/password.

#### Host

The host IP or URL of your Redshift cluster.

#### Port

The Port to be used to connect to Redshift. Default is: `5439`

#### Database

The name of the Redshift database to connect to on the server. Default is: `postgres`

#### User

The name of the user to use for Whaly BI. Default is: `whaly_bi`

#### Password

The password of the user created for Whaly BI

### Step 3: Secure the database connection

Please make sure to properly [whitelist Whaly IPs](/warehouse/postgres/whitelisting-whaly-ips).


# Databricks


# Connect your Databricks

In order to connect your Databricks instance, Whaly needs some credentials. This guide will details the necessary steps:

1. Getting your SQL Warehouse JDBC URL
2. Creation of a Personal Token

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

To connect Databricks to Whaly, you need the following:

* A Databricks Workspace with SQL support (premium and enterprise plans)
* A SQL Warehouse
* Admin rights on the Databricks Workspace

## Getting your SQL Warehouse JDBC URL

In order to connect to your Databricks Workspace, Whaly will need a SQL Warehouse and its JDBC URL:

* Go your Workspace home page
* In the left panel, select "SQL" to enter the SQL space of your Workspace

<figure><img src="/files/x8Dz1IS7AwzuX2vMzBP2" alt=""><figcaption></figcaption></figure>

* Once in the SQL space, click on "SQL Warehouses" in the left panel

<figure><img src="/files/umb7tE603yy0CNXZkNIM" alt=""><figcaption></figcaption></figure>

* In the SQL Warehouses screen, either create a dedicated Warehouse or select an existing one

<figure><img src="/files/jYIUAQA9QN4bf7mOHgkj" alt=""><figcaption></figcaption></figure>

* Once in a Warehouse, click on "Connection details" tab and copy the JDBC URL

<figure><img src="/files/4UvV5HossWTJQqYh21jw" alt=""><figcaption></figcaption></figure>

## Creation of a Personal Token

In order to authenticate on your Databricks Workspace, Whaly needs to have a "Personal Token". In order to create one, please [follow this guide.](https://docs.databricks.com/dev-tools/auth.html#pat)

You can either create a Personal Token on an existing user (simpler way) or create a Service principals and create the Personal Token on it (more secure way but requires doing manual API calls for setup).


# Google BigQuery


# Connect your BigQuery

In order to connect your BigQuery instance, Whaly needs to be connected with your Google Cloud Instance. This guide will details the necessary steps:

1. Finding your Google Cloud Project ID
2. Creation of a Google Cloud Service Account with the proper role

{% hint style="info" %}
Steps where you need to paste info from the google cloud console to Whaly are identified with a :scissors:
{% endhint %}

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

To connect BigQuery to Whaly, you need the following:

* A Google Cloud Project
* Admin rights on the Google Cloud Console

## 1. Find your project ID

You need to grant Whaly access to your BigQuery cluster so we can create and manage tables for your data, and periodically load data into those tables.

* Go to your Google Cloud Console's [projects list](https://console.cloud.google.com/cloud-resource-manager?pli=1).
* :scissors: Find your **Project ID** and paste it into Whaly.

![](/files/zAyXwnxdZ9f5JjsMBgnb)

## 2. Create a Google Cloud service account

In order to give Whaly access to a subset of your Google Cloud account, you have to create a Service Account. In Google Cloud, a service account is a technical user that will have some permissions and credentials to access your cloud ressources.

**A. Create the service account**

In order to create the service account that will be used by Whaly to connect to your BigQuery, see [Google's Creating a service account documentation](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating).

**B. Make the service account a BigQuery admin**

* Go back to the **IAM & admin** tab, and go to the [project members list](https://console.cloud.google.com/iam-admin/iam/project).
* Select **+ Add**.

![](/files/zFY7aUcKJJkTKB32IRvR)

* In the **New Members** field, enter the service account you created in Step 2.A. The service account is the entire email address.
* Click **Select a role > BigQuery > BigQuery User**.

<figure><img src="/files/AHLP0JXDAAFTzB2mjqI1" alt=""><figcaption></figcaption></figure>

**C. Download the service account private key**

:scissors: Then, [create a Private key (JSON) for your service account](https://cloud.google.com/iam/docs/creating-managing-service-account-keys). Open it with your favourite text editor and paste the whole file content into Whaly.


# Grant access to BigQuery datasets

By default, Whaly will only have access to the Datasets created by Whaly connectors. In order to grant access to already existing BigQuery Datasets, you should follow those steps:

1. Go to the BigQuery Admin Console

<figure><img src="/files/EozLQlUlBzXE4ytO4hya" alt=""><figcaption></figcaption></figure>

2. On the left panel, click on one Dataset name (ex. "Days") to open it
3. On the Dataset page, click on "Sharing > Permissions" menu item

<figure><img src="/files/FPnJrSAcnqngtpu1L582" alt=""><figcaption></figcaption></figure>

4. In the side panel that opens, click on "Add Principal"

<figure><img src="/files/G8FcpcugqkFX2VB3y5la" alt=""><figcaption></figcaption></figure>

5. In the "New principals" search bar, select the Service Account configured in Whaly. And in the "Assign roles", select the "BigQuery Data Viewer" role.

<figure><img src="/files/M7votQNiavAsrIMDaBZY" alt=""><figcaption></figcaption></figure>

6. Click on "Save"

<figure><img src="/files/TUBgwoDuDt6PFBUgx4zG" alt=""><figcaption></figcaption></figure>

And that's it! Whaly will now let users import tables from this BigQuery Dataset 🎉


# Enable multi project support

It is possible to query datasets stored in other Google Cloud Project than in the "primary" project that is configured. BigQuery compute cost will still be charged in the "primary" project, but it gives you more flexibility to organize your Warehouse to use multiple projects.

To activate multi project support, you need to do the following in Google Cloud console:

a. Activate the [Cloud Resource Manager API](https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/overview) **on the primary project ID** configured in Whaly

b. Give IAM permissions (Role: **`BigQuery User`** or **`BigQuery Admin`**) to the Whaly Service Account in each of the projects you want to add

c. (only if granted role is **`BigQuery User`** in previous step) For each datasets to the Datasets stored in secondary projects [grant access to Whaly](/warehouse/google-bigquery/grant-access-to-bigquery-datasets).


# Postgres


# Connect your Postgres

Setting up the Postgres destination connector involves setting up Postgres entities (user, grants) through Postgres access, and configuring the Postgres destination connector using Whaly UI.

This page describes the step-by-step process of setting up the Postgres destination connector.

### Step 1: Create a Whaly read only user in Postgres​ <a href="#step-1-set-up-airbyte-specific-entities-in-snowflake" id="step-1-set-up-airbyte-specific-entities-in-snowflake"></a>

To set up the Postgres destination connector, you first need to connect to your Postgres server to run some SQL queries.

```sql
CREATE USER whaly_bi WITH ENCRYPTED PASSWORD 'some_password_here';
GRANT CONNECT ON DATABASE database_name to whaly_bi;
\c database_name
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO whaly_bi;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whaly_bi;
```

If you're using a schema other than `public`, run this command to grant usage permissions to Whaly:

```sql
GRANT USAGE ON SCHEMA schema_name TO whaly_bi;
```

To make sure that future tables you add to the public schema are also available to the `whaly_bi` user, run these commands:

```sql
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON tables TO whaly_bi;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON sequences TO whaly_bi;
```

Depending on your setup, the preceding commands may need to be altered. If another user or role is creating tables that the `whaly_bi` user needs future permissions for, you must specify a *target* role or user to apply the `whaly_bi` user's permission grants for:

```sql
ALTER DEFAULT PRIVILEGES FOR USER <USER_WHO_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON tables TO whaly_bi;
ALTER DEFAULT PRIVILEGES FOR USER <USER_WHO_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON sequences TO whaly_bi;
-- or
ALTER DEFAULT PRIVILEGES FOR ROLE <ROLE_THAT_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON tables TO whaly_bi;
ALTER DEFAULT PRIVILEGES FOR ROLE <ROLE_THAT_CREATES_TABLES> IN SCHEMA public GRANT SELECT ON sequences TO whaly_bi;
```

See [`ALTER DEFAULT PRIVILEGES`](https://www.postgresql.org/docs/9.4/sql-alterdefaultprivileges.html) on PostgreSQL's website for more information.

### Step 2: Set up Postgres as a destination in Whaly <a href="#step-3-set-up-snowflake-as-a-destination-in-airbyte" id="step-3-set-up-snowflake-as-a-destination-in-airbyte"></a>

Navigate to the Whaly UI to set up Postgres as a destination. You can authenticate using username/password.

#### Host

The host IP or URL of your Postgres server. It can be a Read-only replica or a regular Postgres server.

#### Port

The Port to be used to connect to Postgres. Default is: `5432`

#### Database

The name of the Postgres database to connect to on the server. Default is: `postgres`

#### User

The name of the user to use for Whaly BI. Default is: `whaly_bi`

#### **Password**

The password of the user created for Whaly BI

### Step 3: Secure the database connection

Please make sure to properly [whitelist Whaly IPs](/warehouse/postgres/whitelisting-whaly-ips).


# Whitelisting Whaly IPs

In order to let Whaly connect to your Postgres warehouse, you need to whitelist the following IPs for inbound connections.

Here is the full list of IPs to whitelist:

```
8.34.208.0/23
8.34.211.0/24
8.34.220.0/22
23.251.128.0/20
34.22.0.0/16
34.76.0.0/14
34.140.0.0/16
35.187.0.0/17
35.187.160.0/19
35.189.192.0/18
35.190.192.0/19
35.195.0.0/16
35.205.0.0/16
35.206.128.0/18
35.210.0.0/16
35.220.96.0/19
35.233.0.0/17
35.240.0.0/17
35.241.128.0/17
35.242.64.0/19 
104.155.0.0/17 
104.199.0.0/18 
104.199.66.0/23 
104.199.68.0/22 
104.199.72.0/21 
104.199.80.0/20 
104.199.96.0/20
130.211.48.0/20
130.211.64.0/19
130.211.96.0/20 
146.148.2.0/23
146.148.4.0/22
146.148.8.0/21
146.148.16.0/20
146.148.112.0/20
192.158.28.0/22
```


# Snowflake


# Connect your Snowflake

Setting up the Snowflake warehouse connector involves setting up Snowflake entities (warehouse, database, schema, user, and role) in the Snowflake console, and configuring the Snowflake Warehouse connector using Whaly UI.

This page describes the step-by-step process of setting up the Snowflake warehouse connector.

### Prerequisites[​](https://docs.airbyte.com/integrations/destinations/snowflake/#prerequisites) <a href="#prerequisites" id="prerequisites"></a>

* A Snowflake account with the [ACCOUNTADMIN](https://docs.snowflake.com/en/user-guide/security-access-control-considerations.html) role. If you don’t have an account with the `ACCOUNTADMIN` role, contact your Snowflake administrator to set one up for you.

## Step 1: Set up Whaly-specific entities in Snowflake​ <a href="#step-1-set-up-airbyte-specific-entities-in-snowflake" id="step-1-set-up-airbyte-specific-entities-in-snowflake"></a>

To set up the Snowflake warehouse connector, you first need to create Whaly-specific Snowflake entities (a warehouse, database, schema, user, and role) to read data into Snowflake, track costs pertaining to Whaly, and control permissions at a granular level.

You can use the following script in a new [Snowflake worksheet](https://docs.snowflake.com/en/user-guide/ui-worksheet.html) to create the entities:

1. [Log into your Snowflake account](https://www.snowflake.com/login/).
2. Edit the following script to change the password to a more secure password and to change the names of other resources if you so desire.
3. Execute the script as an `ACCOUNTADMIN` user (check on the top right corner of the Worksheet interface).

{% hint style="info" %}
**Note:** Make sure you follow the [Snowflake identifier requirements](https://docs.snowflake.com/en/sql-reference/identifiers-syntax.html) while renaming the resources.
{% endhint %}

```sql
-- Set variables (these need to be uppercase)
set whaly_bi_username = 'WHALY_BI_USER';
set whaly_bi_password = 'you_should_change_me';

-- This shouldn't be modified
set whaly_bi_role = 'WHALY_BI_ROLE';
set whaly_bi_warehouse = 'WHALY_BI_WAREHOUSE';

begin;

-- create Whaly roles
use role securityadmin;
create role if not exists identifier($whaly_bi_role);
grant role identifier($whaly_bi_role) to role SYSADMIN;

-- create Whaly user
create user if not exists identifier($whaly_bi_username)
password = $whaly_bi_password
default_role = $whaly_bi_role
default_warehouse = $whaly_bi_warehouse;

grant role identifier($whaly_bi_role) 
    to user identifier($whaly_bi_username);

-- change role to sysadmin for warehouse / database steps
use role sysadmin;

-- create Whaly warehouse
create warehouse if not exists identifier($whaly_bi_warehouse)
-- set the size based on your dataset
warehouse_size = medium
warehouse_type = standard
auto_suspend = 120
auto_resume = true
initially_suspended = true
statement_timeout_in_seconds = 600;

-- grant Whaly Warehouse access
grant USAGE
    on warehouse identifier($whaly_bi_warehouse)
    to role identifier($whaly_bi_role);

-- create Private Whaly database (used for SQL queries schema inference)
create database if not exists WHALY_PRIVATE;

grant USAGE
    on database WHALY_PRIVATE
    to role identifier($whaly_bi_role);

create schema if not exists WHALY_PRIVATE.SQL_SCHEMA_INFER;

grant USAGE, CREATE VIEW
    on schema WHALY_PRIVATE.SQL_SCHEMA_INFER
    to role identifier($whaly_bi_role);

commit;
```

## Step 2: Set up Snowflake as a Warehouse in Whaly <a href="#step-3-set-up-snowflake-as-a-destination-in-airbyte" id="step-3-set-up-snowflake-as-a-destination-in-airbyte"></a>

Navigate to the Whaly UI to set up Snowflake as a destination. You can authenticate using username/password.

#### Account ID

The Account ID as an URL. Ex. [`https://xxxxxxx-yyyyyyy.snowflakecomputing.com`](https://xxxxxxx-yyyyyyy.snowflakecomputing.com) . It can be found in Snowflake web UI in **Admin > Accounts** and then you cal click on the 🔗 icon next to the account name in the table.

#### User

The username you created in Step 1 to allow Whaly to access the database. Example: `WHALY_BI_USER`

#### Password

The password associated with the business intelligence user.

## How to get the Snowflake Account URL?

#### If you have a standard Snowflake edition

1. Go on the bottom right part of you screen and open your Account Selector.
2. On the tooltip, select the proper account and click on "Copy account URL"

<figure><img src="/files/lRIR7OhiFN3fDI5SzHlm" alt=""><figcaption></figcaption></figure>

#### If you have a multi cluster Snowflake edition

1. Go into the "**Admin > Account**" panel on the right side of the screen
2. Next to your account name, click on the 🔗 icon which will copy the URL on your clipboard!

![](/files/UBfTG6itaKwIBlVzZKCn)


# Giving access to Snowflake data

By default, the Whaly platform only has access to data that was imported using Whaly connectors.

If you have data already stored inside your Snowflake account that you want to access within Whaly BI, you can do it using the following commands:

{% hint style="info" %}
Please run those commands with the `ACCOUNTADMIN` role to have the proper sharing rights!
{% endhint %}

### 1. Give access to Whaly BI to a Snowflake database

```
set whaly_bi_role = 'WHALY_BI_ROLE';
set snowflake_database = 'INSERT_PROPER_DATABASE_NAME_TO_EXPOSE_IN_WHALY_BI';

grant USAGE
    on database identifier($snowflake_database)
    to role identifier($whaly_bi_role);
```

This will get Whaly access to the database but not to the data stored inside it. Follow the next steps to give access to the proper part of the database to Whaly ⤵️

### 2. Wide access | Give access to Whaly BI to ALL Schemas and ALL Tables located in a Snowflake database

```
set whaly_bi_role = 'WHALY_BI_ROLE';
set snowflake_database = 'INSERT_PROPER_DATABASE_NAME_TO_EXPOSE_IN_WHALY_BI';

USE DATABASE identifier($snowflake_database);
grant USAGE
    on all schemas in database identifier($snowflake_database)
    to role identifier($whaly_bi_role);
grant SELECT 
    on all tables in database identifier($snowflake_database)
    to role identifier($whaly_bi_role);
grant SELECT 
    on future tables in database identifier($snowflake_database)
    to role identifier($whaly_bi_role);
```

{% hint style="info" %}
Whenever adding new schemas into your Snowflake database on which you to get access to Whaly, please run the following query :arrow\_down\_small:
{% endhint %}

```
set whaly_bi_role = 'WHALY_BI_ROLE';
set snowflake_database = 'INSERT_PROPER_DATABASE_NAME_TO_EXPOSE_IN_WHALY_BI';
set snowflake_schema = 'INSERT_PROPER_SCHEMA_NAME';

USE DATABASE identifier($snowflake_database);
grant USAGE
    on schema identifier($snowflake_schema)
    to role identifier($whaly_bi_role);
```

### 2bis. Granular access | Give access to Whaly BI to a SINGLE Schema and ALL its Tables located in a Snowflake database

```
set whaly_bi_role = 'WHALY_BI_ROLE';
set snowflake_database = 'INSERT_PROPER_DATABASE_NAME_TO_EXPOSE_IN_WHALY_BI';
set snowflake_schema = 'INSERT_PROPER_SCHEMA_NAME';

USE DATABASE identifier($snowflake_database);
grant USAGE
    on schema identifier($snowflake_schema)
    to role identifier($whaly_bi_role);
grant SELECT 
    on all tables in schema identifier($snowflake_schema)
    to role identifier($whaly_bi_role);
grant SELECT 
    on future tables in schema identifier($snowflake_schema)
    to role identifier($whaly_bi_role);
```


# Models sync

{% hint style="info" %}
Whaly offer an [integrated lightweight modelling layer](/data-management/workbench/model-data) that can be seem as "conflicting" with others solutions such as dbt, Keboola and Dataform.

However, this is not the case, both type of Models can and should be used at the same time for different reasons, [read this article to understand why.](/models/models-sync/where-should-my-models-be-managed)
{% endhint %}

Models sync is a set of integrations that enable Whaly to import Models managed by an external modelling solution (dbt Cloud, dbt Core, Keboola, Dataform).&#x20;

Thanks to those integrations, it is possible to surface to Data Consumers all the metadata that were produced in the Modelling layer. This includes:

* Model Documentation import
* Source freshness checks imports
* Models tests results
* Lineage imports

Being able to share those informations with Data consumers by makig it available in Whaly is important to build trust with your stakeholders and make sure that important facts such as pipelines failures are communicated through warnings in the produced Dashboards.

This synchronisation is really helpful when:

a. A dashboard breaks and an analyst is asked to have a look. Having all the modelling information available in Whaly will help them understand what is the issue without having to go back and forth between Whaly and the modelling system. Issues can be resolved more quickly this way.

b. When a pipeline breaks (source sync is late or a data test failed), the Model sync will automatically alerts your data consumers in their dashboards and charts that there is something wrong and prevent them from making bad decisions on top of broken KPIs.

## Understanding the integration

### Models

Models declare in your external modelling solutiom will be created as Models in Whaly. Those models are read only and the generated SQL query will be accessible to your analysts.&#x20;

If your model has a test that renders a column unique, this column will automatically be flagged as the primary key of this model.&#x20;

If your model has associated tests, you can view their results in the preview tab or the information tab.

<figure><img src="/files/yn8JHq8WQlUeskv9o16t" alt=""><figcaption><p>A tested column with passing test</p></figcaption></figure>

All results associated to your model will be available in the information tab under the Run Result card.

<figure><img src="/files/80hCcZIM3xFQ8gksV8WZ" alt=""><figcaption><p>All tests associated to a dataset</p></figcaption></figure>

Please note that we automatically import your lineage as well:

<figure><img src="/files/FFrATXR3ZUEYYzaqEs4b" alt=""><figcaption><p>dataset lineage</p></figcaption></figure>

### Sources

We import your sources as they are defined in your modelling project. The source in your modelling project will create a Source in Whaly and each table as defined under your source will be imported in your Whaly project.&#x20;

This comes with the source freshness as well as any tests associated with your source table.

<figure><img src="/files/YqI0ac9RO9VHxY4RtjQU" alt=""><figcaption><p>Source results</p></figcaption></figure>

## Benefits

### Lifecycle

For any source, model, or test added in your modelling project will be automatically synced on the next period to your Whaly environment, any source, model or test deleted will also be deleted on the next sync. This help you keep up to date and tidy environment.&#x20;

Your analyst can quickly create and iterate on new models in your Whaly environment and when those models are steady enough they can be moved to your modelling environment and replicated in your Whaly instance.

This helps you to get a consistant pace of iteration.

### Lineage Alerts

Since dashboards and exploration lives in Whaly we will display an error on any exploration or charts impacted with a lineage issue. This helps prevent your business users to trust stale data.&#x20;

<figure><img src="/files/DbArLLIzzimzfWGmxcyt" alt=""><figcaption><p>Lineage issue</p></figcaption></figure>


# Where should my models be managed?

There are many great solutions widely adopted by the data community to build and manage your business knowledge through Models such as dbt, Keboola and Dataform. Such tools have helped countless of companies scaling their modelling capabilities.

Those solutions help you use software engineering patterns in your modelling project such as:&#x20;

* documentation
* version control through git
* unit testing
* source freshness
* continuous integration
* continuous deployment
* templatization engine

In the same time, Whaly offers a lightweight modelling layer that enable people to build:

* SQL models
* Flow Models (no-code)&#x20;

In the end, successful data architecture contains Models in both specialised modelling solutions and in Whaly in the same time, let's dive in to understand why Whaly models exists.

## Working as a software engineer comes at a cost

The reason why modern modelling solution are so good is that they took inspiration of the Software engineering best practises. But it is also one of their biggest issue.

When you switch to a code based modelling layer, your people and your internal tooling must evolve to meet the new requirement that comes with the "software engineering" process.

{% hint style="info" %}
As a reminder, the common "Software engineering" process is:

1. Getting a requirement from a business team
2. Implementing the requirement on a local branch/copy of the project
3. Locally testing the new implementation
4. Opening a Pull Request on your favorite git tool (github, gitlab, ...)
5. Have a peer review and approve the Pull Request
6. Merge the pull request
7. Check production state after the pull request has been merged
   {% endhint %}

&#x20;This is a powerful but complex process that has its own benefits such as:

* Each development must be approved by a peer leading to
  * A more consistent codebase
  * Less bugs pushed in production
* Each features can be tested locally leading to
  * A smoother dev experience
  * Less time spent debugging and more time spent fixing bugs and working on new features

But while this process is more robust, it is quite slow and requires the use of a lot of tools (git, CI/CD, etc.) which means that fewer people can follow it because of lack of skills and time.

In the end, it lead to fewer and slower data breakthroughs, leading to deceptiveness from your business users standpoint.

## What are Whaly models and how they complete models managed by an external solution

Whaly models are lightweight and easy to create. SQL knowledge is not even required as they also exists in a visual "flow" fashion. This way, it's very easy for anyone in your organisation to create and share their own Models, similar to what they could do with a spreadsheet.

In the same time, those lightweights models can be used and shared inside Whaly in the same way as a Modelling solution model could be used: in the end, the produced dashboards looks the same.

Whaly models can be individually "migrated" to the specialised solution once your organisation wants to get a better level of control over them.

## Summary

| Model type                    | Pros                                                                                                                    | Cons                                                                                                    | When to use                                                                                                                                                                            |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Whaly models                  | <ul><li>Easy/fast to create for anyone</li><li>Exists in code (SQL) or no-code way</li></ul>                            | <ul><li>Can result in "fragile" data hierarchy</li><li>No strong governance on Models changes</li></ul> | <ul><li>When prototyping a data project</li><li>When working with business users (Product Managers, SalesOps, RevOps)</li></ul>                                                        |
| dbt, Keboola, Dataform models | <ul><li>Comes with a very mature process to produce high quality models</li><li>Very extensible (macros, ...)</li></ul> | <ul><li>Slow/costly to create</li><li>Only come as code (SQL/Python)</li></ul>                          | <ul><li>When industrialising a project</li><li>When a model is important and data quality matters</li><li>For slow changing models, once the business requirements are clear</li></ul> |


# dbt Cloud


# Configuration

## Prerequisites

In order to use this integration you need:

* An account on [dbt cloud](https://www.getdbt.com/)
* An api access on [dbt cloud](https://www.getdbt.com/) (please note that only paid plan have an API access)
* A service token on the said account
* A job that outputs a `manifest.json` & `run-results.json`
* A job that outputs `sources.json`&#x20;

### Configure your service token on dbt Cloud

Go to your Account **Settings > Service Token** and create a new service token. Give this Service Token access to your desired project as well as the following roles:

* Read Only

<figure><img src="/files/LpICKObBYmRhcgt0rFhD" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Once your service token is created, copy the key because you will not be able to access it again and save it for later.
{% endhint %}

### Configure your project to output the proper artifacts

In order to get access to your `manifest.json` , `run_results.json` and `source.json` using the API, you should edit your Project Details and associate it with the 2 Jobs that are producing them.

* Documentation Job: Associate it with a Job that output `manifest.json` & `run_results.json`
* Source Freshness: Associate it with a Job that output `source.json`

{% hint style="info" %}
The mapping between the CLI options and the produced outputs is available in [dbt documentation](https://docs.getdbt.com/reference/artifacts/dbt-artifacts#when-are-artifacts-produced).
{% endhint %}

Please reference the proper jobs at the project level:

<figure><img src="/files/5FqRwavBy15p2nfdH65o" alt=""><figcaption></figcaption></figure>

### Find your Account ID and Project ID&#x20;

Open the job that you have configured at the previous step and extract the Account Id and Project Id from your URL.

The url should look like:

```
https://cloud.getdbt.com/next/deploy/<Account Id>/projects/<Project Id>/jobs
```

## Configure Whaly

Open Whaly and go to the [Settings](/workspace/settings). On the settings please click on **Storage Admin > Models Sync**. You should see a page like this:

<figure><img src="/files/NE0Ax7HEAfa9fw01gbhH" alt=""><figcaption></figcaption></figure>

Click on **Activate dbt Cloud Sync** for modeling.&#x20;

You will then be prompted to enter your Service Token, your Account Id as well as your Project Id.

Once this is done, go into the Workbench and you'll see the dbt icon on the left bar.

Click on it to display the syncs panel. Click on a previous sync to checks its logs or click on the plus sign at the top of the page to trigger a sync between Whaly and dbt Cloud.

<figure><img src="/files/qkV21NNPSw13Zib1NWEa" alt=""><figcaption></figcaption></figure>


# Exposing models into Whaly

By default, when synchronising your dbt Cloud project with Whaly, you won't see any models appearing in the workbench.

This is because most of your models and sources managed in dbt should not be exposed in your Business Intelligence as those are really the fundamental building blocks of your modelling data structure. You want to expose in your consumption layer only the most prepared and enriched models.

In order to expose a model or a source into Whaly, you'll need to flag them in your dbt project directly by adding a specific meta.

## Exposing a model

In the YAML definition of the model, please add the following meta to make it available in Whaly:

```yaml
meta:
    expose_in_whaly: true
```

Here is an example:

```yaml
version: 2

models:
    - name: jaffle_customers
      meta:
        expose_in_whaly: true # <===
      description: "A transformed version of customers through dbt"
      columns:
          - name: customer_id
            description: "The primary key for this table"
            tests:
                - unique
                - not_null
```

## Exposing a source

In the YAML definition of the source, please add the following meta to the source **and to all tables** that you want to expose to make it available in Whaly:

```yaml
meta:
    expose_in_whaly: true
```

Here is an example:

```yaml
version: 2 
sources: 
  - name: "jaffle_shop" 
    schema: "jaffle_shop"
    meta:
      expose_in_whaly: true # <===
    freshness: 
      warn_after: 
        count: 12 
        period: "hour" 
      error_after: 
        count: 24 
        period: "hour" 
    loaded_at_field: "_whaly_synced" 
    tables: 
      - name: "customer" 
        identifier: "customer"
        description: "A person who buys goods or services from a Jaffle shop."
        meta:
          expose_in_whaly: true # <===
        columns:
        - name: customer_id
          description: This is a unique identifier for a customer
          tests:
            - unique
            - not_null
        - name: first_name
          description: Customer's first name. PII.
        - name: last_name
          description: Customer's last name. PII.
```


# Persistence Engine

When you start to heavily using models you might experience the overall loading time of reports increasing. That's because your warehouse is doing too much at query time. You might also react the limits of your warehouse and some queries might not work anymore.

Or you might want to reuse a Whaly model in an alternative tool such as another visualisation tool or in a reverse ETL.

In order to remediate to both those issues you can materialise your models as view or as tables by using Whaly Persistence Engine.

Whaly Persistence Engine will compute the lineage of your Models and depending on the materialisation configuration done for each model, it will write down its results in your Warehouse.

Future queries done by dashboards and charts will be done on top of those materialisation results.

Persistence Engine can materialise each model in 3 ways:

* No materialisation: This is keeping the Model "virtual" and means that it won't be written to your Warehouse.
* Materialise as a View: This will persist only the SQL query of the models in your Warehouse but each future read will still execute the SQL query. This won't save you compute costs but it will expose the Models in your Warehouse and each query will always returns the most up to date results.
* Materialise as a Table: This will persist the results of the SQL query in your Warehouse. This means that future reads won't execute the Model SQL again but only read the previous result. This is a cost saver but Data Consumer won't have access to the most up to date data, only the one of the last materialisation job run.


# Configuration

## Activate the Persistence Engine

In order to activate the Persistence Engine, you have to go to the Settings panel. Once there, open the "Storage > Persistence Engine screen".

You should have access to this screen:

<figure><img src="/files/UDDJzN4axkF59WEPtu4Z" alt=""><figcaption></figcaption></figure>

From there, you can:

* Activate or disable the Persistence Engine
* Set the schedule period of the Materialization job
* Set the default database and schema the models will be written to in your Warehouse

Once you're done, click on "Save" at the top right.

## Configure a Model materialization configuration

For each model that you want to materialize, go into the Workbench and then click on the Model name. Then go into the "Information" panel.

From there, you'll see the Materialization section that will show you the current configuration for this model:

<figure><img src="/files/n7XyGawcsa4ZfJ7QOl2N" alt=""><figcaption></figcaption></figure>

By clicking on the "Materialize" button, you'll be able the update the configuration:

<figure><img src="/files/TFd9GEi2jssd3i9yV4CK" alt=""><figcaption></figcaption></figure>


# Snowflake

Setting up the Persistence Engine for Snowflake involves setting up Snowflake entities (warehouse, database, schema, user, and role) in the Snowflake console.

This page describes the step-by-step process of setting up the Snowflake destination connector.

### Prerequisites[​](https://docs.airbyte.com/integrations/destinations/snowflake/#prerequisites) <a href="#prerequisites" id="prerequisites"></a>

* A Snowflake account with the [ACCOUNTADMIN](https://docs.snowflake.com/en/user-guide/security-access-control-considerations.html) role. If you don’t have an account with the `ACCOUNTADMIN` role, contact your Snowflake administrator to set one up for you.

### Step 1: Set up Whaly-specific entities in Snowflake[​](https://docs.airbyte.com/integrations/destinations/snowflake/#step-1-set-up-airbyte-specific-entities-in-snowflake) <a href="#step-1-set-up-airbyte-specific-entities-in-snowflake" id="step-1-set-up-airbyte-specific-entities-in-snowflake"></a>

To set up the Snowflake destination connector, you first need to create Whaly-specific Snowflake entities (a warehouse, database, schema, user, and role) with the `OWNERSHIP` permission to write data into Snowflake, track costs pertaining to Whaly, and control permissions at a granular level.

You can use the following script in a new [Snowflake worksheet](https://docs.snowflake.com/en/user-guide/ui-worksheet.html) to create the entities:

1. [Log into your Snowflake account](https://www.snowflake.com/login/).
2. Edit the following script to change the password to a more secure password and to change the names of other resources if you so desire.
3. Execute the script as an `ACCOUNTADMIN` user (check on the top right corner of the Worksheet interface).

{% hint style="info" %}
**Note:** Make sure you follow the [Snowflake identifier requirements](https://docs.snowflake.com/en/sql-reference/identifiers-syntax.html) while renaming the resources.
{% endhint %}

```
-- Set variables
set whaly_scratch_database = 'SCRATCH';
set whaly_scratch_schema = 'SCRATCH';

-- This shouldn't be modified
set whaly_bi_role = 'WHALY_BI_ROLE';

begin;

-- change role to sysadmin for warehouse / database steps
use role sysadmin;

-- create Whaly scratch database
create database if not exists identifier($whaly_scratch_database);

-- grant Whaly database access
grant OWNERSHIP
    on database identifier($whaly_scratch_database)
    to role identifier($whaly_bi_role);

-- create scratch schema
use database identifier($whaly_scratch_database);
create schema if not exists identifier($whaly_scratch_schema);

grant OWNERSHIP on schema identifier($whaly_scratch_schema)
	to role identifier($whaly_bi_role);

commit;
```


# Check Materialisation runs status

Once the Persistence Engine is activated, it'll run at the specified schedule period. In order to validate that the Persistence are going fine and troubleshoot any issues you could have, you can check the Persistence runs status in the Workbench.

In the Workbench, once the Persistence Engine is activated, you'll have a new item that appears on the left panel, click on it to see past Persistence Runs and trigger a new one:

<figure><img src="/files/KCNk1XyXAeypX7LMiVJO" alt=""><figcaption></figcaption></figure>

By clicking on the + icon, you'll be able to start a Persistence Runs directly.


# Navigating the workbench

## Top menu

The workbench top menu helps you quickly create datasets and switch through views, but also find help.

<figure><img src="/files/sbfUCOKKEKtA1VflOETK" alt=""><figcaption><p>Top Menu</p></figcaption></figure>

## View Selector

The view selector helps you navigate through different kind of objects such as your datasets and workbench executions.

<figure><img src="/files/619WPzGouRR4bhB1Ewh4" alt=""><figcaption><p>View Selector</p></figcaption></figure>

## Tab bar

Each time you click on a record we open a tab so you can easily navigate through tabs&#x20;

<figure><img src="/files/GyUBMv8eu8RKVHKqwaUI" alt=""><figcaption><p>Tab bar</p></figcaption></figure>

## Content view

This is where you will actually interact with your data.

<figure><img src="/files/KvJ7ZjXq2U93qnTU60ay" alt=""><figcaption><p>Content View</p></figcaption></figure>

### Dataset Content View

The dataset content view has three tabs

* **Preview**\
  Gives you a preview (first 3000 rows) of what is in your table
* **Configuration (only for models)**\
  This is where you can edit your Flow or SQL query for the models managed by Whaly
* **Informations**\
  This is where you can edit meta data for your dataset such as Primary keys, relationships, ...


# Modeling

The main purpose of the workbench is to let you:

1. Manage what data is available to Builders to create Exploration on
2. Import Raw Data from your warehouse and third parties
3. Model data to fit your business needs

In this section you'll learn:

{% content-ref url="/pages/tJZaQ8m9oub5hCZ3ETOw" %}
[Understanding Datasets](/data-management/workbench/understanding-datasets)
{% endcontent-ref %}

{% content-ref url="/pages/5yqmPu4c64fEQBDFI0tU" %}
[Model Data](/data-management/workbench/model-data)
{% endcontent-ref %}

{% content-ref url="/pages/kC2H7hHKaNNjyFq3RJVw" %}
[Import raw data](/data-management/workbench/import-raw-data)
{% endcontent-ref %}


# Understanding Datasets

## What is a dataset?

A dataset on Whaly represents any kind of data that is outputted by your warehouse and made available through the Whaly interface. Models are datasets, raw data imported from your warehouse or from a third party are also datasets. When a dataset is generated by a SQL or Flow query we call that a Model.

All datasets share common informations such as:

* A name and a description
* Primary keys
* Relationships to other datasets
* Drills definition

Models have specific capabilities such as:

* Materialization

In this section you'll learn how to configure a dataset.&#x20;

If you are looking to model data jump to

{% content-ref url="/pages/5yqmPu4c64fEQBDFI0tU" %}
[Model Data](/data-management/workbench/model-data)
{% endcontent-ref %}

If you are looking to import datasets either from Third Parties or from your own warehouse jump to

{% content-ref url="/pages/kC2H7hHKaNNjyFq3RJVw" %}
[Import raw data](/data-management/workbench/import-raw-data)
{% endcontent-ref %}


# General Information

## Displaying dataset information

You can display the dataset information by opening any dataset and going to the **information** tab

<figure><img src="/files/derXNJ83OQWsMBgOMrcR" alt=""><figcaption></figcaption></figure>

### Name & description

In this tab you can edit the dataset name as well as the dataset description. Creating clear names and description are crucial for proper maintenance and scalability of the project. Gather up with your team and decide on a taxonomy to adopt

### Schema

The schema block allow you to manage primary keys but also to view the output of the schema with all primary keys an foreign keys.

Learn more on how to manage primary keys

{% content-ref url="/pages/bz626amj0hyeLu269TgV" %}
[Primary Keys](/data-management/workbench/understanding-datasets/primary-keys)
{% endcontent-ref %}

### Relationships

Learn more on how to manage relationships here:

{% content-ref url="/pages/GodocfwavwIvOVYU6pGD" %}
[Relationships](/data-management/workbench/understanding-datasets/relationships)
{% endcontent-ref %}

### Delete

You can delete a dataset by **hovering** it in the **View Selector** under **Model** and clicking on the **three dots** or by clicking on the delete button in the **information** tab.

{% hint style="info" %}
Be careful when deleting a model this might break explorations that are using is or models it has been referenced in.
{% endhint %}

{% hint style="warning" %}
You cannot delete datasets that are managed by Whaly (meaning datasets created by the third party sources) In order to delete those datasets stop syncing them in the source panel.
{% endhint %}


# Drills

Drills are a way of configuring what should be displayed to the end users when they interact with reports by clicking on charts.

It's a great way to:

* Allow your viewers to go beyond just a report aggregated data&#x20;
* Add more interactivity to the report

## Why using drills?

When viewers will start consuming your reports, they will have additional questions.&#x20;

> Why are my sales going up or down?&#x20;
>
> What are the deals currently in closed won or lost? etc.&#x20;

To give more flexibility and level of interaction to viewers, you can set up drills in the [Workbench](/data-management/workbench) that will then be automatically available to all your charts in the reporting section.

## How can I configure drills?

In the workbench, at the bottom left corner of your window, click on the "**Drills**" button

<figure><img src="/files/hnnktaDMK3NaT9gnaN0P" alt=""><figcaption><p>Configuring drills</p></figcaption></figure>

From here you can pick any property you want to be available as a Drill and reorder them the way you want by dragging and dropping them.

{% hint style="info" %}
Please note that by default drills show the primary key
{% endhint %}


# Relationships

Relationship are a way of telling Whaly how your datasets are linked together.&#x20;

It's a great way to:

* Combine data from various source&#x20;
* Create detailed explorations

## How can I configure relationship?

To configure a dataset relationship, go to the **information** tab and then scroll to the relationship block and click on **Add a relationship.**

<figure><img src="/files/xtQ5cQKnboyRu3QNfSZu" alt=""><figcaption><p>Adding relationships</p></figcaption></figure>

In order to add a relationship you need to provide:

* A dataset which will be related to the current dataset
* A column from the current dataset&#x20;
* A column from the related dataset that will match the one selected above in values and in type (example => String can only match String columns)
* A type of relationship&#x20;
  * Has many
  * Belongs to
  * Has one

## Understanding Relationship Type

Let's imagine we have the three following tables:

**Orders**

```
| order_id | amount   | user_id  |
|----------|----------|----------|
| 1        | 90       | 1        | 
| 2        | 10       | 1        |
| 3        | 50       | 2        |
| 4        | 30       | 1        |
| 5        | 20       | 2        |
```

**Users**

```
| user_id  | name            | address_id  |
|----------|-----------------|-------------|
| 1        | Rick Sanchez    | 1           | 
| 2        | Archer Sterling | 2           |
```

**Address**

```
| address_id  | name                 |
|-------------|----------------------|
| 1           | 6910 Smith Residence |
| 2           | Penthouse NYC        |
```

In this example a User has multiple orders therefore when setting up relationships we will do:

**Relationship 1:**

* **From dataset**: User
* **To dataset:** Order
* **Type** has many
* **From Column**: user\_id
* **To column**: : user\_id

Please note that **"has many"** is the opposite of **"belongs to"**, therefore this relationship would have been legit too:

**Relationship 2:**

* **From dataset**: Order
* **To dataset:** User
* **Type** belongs to
* **From Column**: user\_id
* **To column**: : user\_id

{% hint style="info" %}
Whenever a relationship is created, the symmetric relationship is automatically created on the other dataset.
{% endhint %}

As we have the same number of rows in both the Users and Address as a User can have a single Address and vice versa, we will create a one to one relationship:

**Relationship 3:**

* **From dataset**: User
* **To dataset:** Address
* **Type:** has one
* **From Column**: address\_id
* **To column**: address\_id

{% hint style="warning" %}
The "has one" relationship is quite rare in real world, it's relevant when you have exactly the same number of rows in the two related datasets.
{% endhint %}


# Primary Keys

When configuring a external Dataset into Whaly, whether it is a Table Import from your Warehouse or when saving a Model (SQL or No-code), you'll have to configure a the set of columns that compose the Primary Key.

Simply put, the Primary Key should be a way to uniquely identify a row in the table. So 2 rows in the table shouldn't have the same values in the columns that are composing the primary key.

#### Example 1:

```
| fruit_id | name     |
|----------|----------|
| 1        | Banana   |
| 2        | Apple    |
| 3        | Orange   |
| 4        | Eggplant |
| 5        | Avocado  |
```

In this table, every row has a different value in the `fruit_id` column. Hence, the `fruit_id` column can be used to uniquely identify all the rows of the table.

Primary Key = `fruit_id` ✅

#### Example 2:

```
| event_date | event_name      | channel    | source       | campaign_id | spend  | 
|------------|-----------------|------------|--------------|-------------|--------|
| 2022-01-01 | Marketing Spend | Search Ads | Google Ads   | 123         | 18.67  |
| 2022-01-01 | Marketing Spend | Search Ads | Google Ads   | 456         | 54.21  |
| 2022-01-02 | Marketing Spend | Search Ads | Google Ads   | 456         | 48.21  |
| 2022-01-01 | Marketing Spend | Social Ads | Facebook Ads | 102212210   | 54.21  |
| 2022-01-01 | Marketing Spend | Social Ads | Facebook Ads | 441215442   | 126.46 |
| 2022-01-02 | Marketing Spend | Social Ads | Facebook Ads | 102212210   | 214.21 |
```

On this example, many columns contains the same value for different rows. Ex. `event_date` column contains multiple times the value "2022-01-01" for different rows.

Same thing for:

* `event_name`
* `channel`&#x20;
* `source`
* `campaign_id`

Hence, those columns **can't be used individually as the Primary Key.**

However, taken all together, `event_date` + `event_name` + `channel` + `source` + `campaign_id` columns are producing a combinaison of values that are unique for each row in the table. If we only keep those columns in the above tables, we have:

```
| event_date | event_name      | channel    | source       | campaign_id |
|------------|-----------------|------------|--------------|-------------|
| 2022-01-01 | Marketing Spend | Search Ads | Google Ads   | 123         |
| 2022-01-01 | Marketing Spend | Search Ads | Google Ads   | 456         |
| 2022-01-02 | Marketing Spend | Search Ads | Google Ads   | 456         |
| 2022-01-01 | Marketing Spend | Social Ads | Facebook Ads | 102212210   |
| 2022-01-01 | Marketing Spend | Social Ads | Facebook Ads | 441215442   |
| 2022-01-02 | Marketing Spend | Social Ads | Facebook Ads | 102212210   |
```

Each row has a unique combinaison of those columns, together they are forming the **Primary Key** 👍

Primary Key = `event_date` + `event_name` + `channel` + `source` + `campaign_id` ✅

### Why is the Primary Key important?

In order for a join to work in an Exploration when having Related Tables, it is necessary to define a **Primary Key** as specified below. It is a requirement when a join is defined so that Whaly can handle row multiplication issues.

Let's imagine you want to calculate`Order Amount` by `Order Item Product Name`.&#x20;

In this case, `Order` rows will be multiplied by the `Order Item` join due to the `hasMany` relationship between `Order` and `Order Item` as it will be a LEFT JOIN.

It is known as the JOIN Fan Out issue.

In order to produce correct results, Whaly will select distinct Primary Keys from `Order` first and then will join these primary keys with `Order` to get the correct `Order Amount` sum result.


# Cache

Any datasets managed in Whaly has several properties that manage its performance. You can materialize the datasets as table to make complex query run smoother [(read about materialization)](/models/persistence-engine#materialize-as-table) and you can also manage the way Whaly will update its cache when user query data on this particular dataset from the workbench. In order to better understand how cache is working on Whaly you can [read more here](/platform-concepts/caching#cache-implementation).

## Why do we use cache?

We pride ourselves into providing a great experience to all data consumer in getting query result fast. Moreover, we don't want your datawarehouse bill to go through the roof when your adoption grows. That's why we give you means to control how your cache is working to make the best use of it.

## Managing the cache strategy

In order to manage the cache strategy, please **open any dataset** on the workbench and click on **Information**, then you can find a **Cache Strategy** card with your card option. Please note that by default all dataset created from Whaly's sources will have the cache strategy set up to use the `_whaly_synced` column that is automatically created. Otherwise datasets will be created with a `2 minutes` cache strategy.

<figure><img src="/files/E2pHt7cpGCIq6AtApdoe" alt=""><figcaption><p>Editing cache</p></figcaption></figure>

{% hint style="info" %}
Please note that each time you are changing the underlying SQL query or adding/editing new dimensions and metrics to exploration, this also reset the cache.
{% endhint %}

## Understanding  cache options

### Renew cache after a period of time

When this option is selected, every query done on this dataset from an exploration will be kept in cache during the period. If your underlying data change during this period, next queries will not update until the period is over. &#x20;

### Renew cache based on a column value

Each time a query is played we will run the following query:

```sql
select max(COLUMN_NAME) from DATASET_SQL
```

Whenever the data changes, we will drop the cache and renew the query. This is useful when you are plugged directly to tables filled by your ETL as usually they give you insight on when was the last time a query was updated.

### Renew cache based on a sql query

You can also run your own query to get access to your table metadata or more. This allow you  to have more control on how to manage cache.

## Removing cache

There are no straightforward way to remove the cache, but you can write a sql query that always return the current timestamp in order to break the cache for each query.


# Model Data

## What is a Model ?

A model is a [dataset](/data-management/workbench/understanding-datasets) that has been generated by a user. It can either be a SQL Model or a Flow Model depending on your capabilities to write SQL queries.

In order to better understand the differences between the two types of models, please refer to:

{% content-ref url="/pages/uUfDkx5aU3FPCZ2YD8hq" %}
[SQL Models](/data-management/workbench/model-data/sql-models)
{% endcontent-ref %}

{% content-ref url="/pages/s90hg6VPt9kTlcvRVehL" %}
[Flow Models](/data-management/workbench/model-data/flow-models)
{% endcontent-ref %}

Please note that a model can reference another model, therefore you can build foundational models that&#x20;


# SQL Models

SQL Models help you transform data using your warehouse SQL implementation on Whaly interface.

It's a great way to:

* Go beyond Flows capabilities&#x20;
* Use a language you are already familiar with (whaly works with your warehouse SQL so no need to learn a new one)
* Start creating SQL queries that you can compose

## Creating a SQL Model

In order to create a SQL Model, open your **View Selector** on **Data**, click on the **+ button** next to models and select **SQL model**. You can also click on **New** > **Model** > **SQL Model.**

<figure><img src="/files/bMRqFVpoMa3iJw3umyyY" alt=""><figcaption><p>Create a SQL Model</p></figcaption></figure>

## Updating a SQL Model

You can modify your SQL model query whenever you need to. In order to do click on the configuration tab, modify the query, run the query (you can save a query only if it outputs data). Before saving data we ask you to provide us the Primary Keys of your model so we know how to use it in an exploration.

<figure><img src="/files/lbzDRmLdbuqRjsZfJzMd" alt=""><figcaption><p>Save a query</p></figcaption></figure>

## Use Composition in your SQL queries

It is very useful to break complicated models into smaller ones that can be more easily managed and more easily debugged. In order to do so Whaly offers you the capability to compose your SQL Queries. It means that you can reference any Sources or Models in your current query and the Whaly query engine will automatically to the interpolation for you.

In order to reference another query, start typing the name of your model or the name of your raw dataset and then hit enter. It should be highlighted in your query in blue. You can click on the dataset reference to open it in a new tab if you wish to introspect it.&#x20;

<figure><img src="/files/gQVSa9QEqNF2K981TxFH" alt=""><figcaption></figcaption></figure>


# Flow Models

## What is a Flow Model

A flow model allow data savvy users to model their data without having to rely on SQL to do so. This allow power business users to:

* Create new derived tables
* Easily combine data from various sources without coding
* Bring data mesh capabilities to your whole company

In the section you'll learn:

{% content-ref url="/pages/x6iBiWhrbaiXV1447Crv" %}
[Create a Flow](/data-management/workbench/model-data/flow-models/create-a-flow)
{% endcontent-ref %}

{% content-ref url="/pages/BUFcjiqP1r8hFoHpsR6E" %}
[Flow steps](/data-management/workbench/model-data/flow-models/flow-steps)
{% endcontent-ref %}

{% content-ref url="/pages/yxKw8DB54NwVX5Ktw286" %}
[Update a Flow](/data-management/workbench/model-data/flow-models/update-a-flow)
{% endcontent-ref %}


# Create a Flow

In order to create a Flow, you can either start from scratch or create a Flow from an existing dataset.

To create a Flow, go to D**ata** in the **View Selector** and click on the **+ button** next to **Models.** This should open a panel asking which kind of model you want to create, then click on **Flow.**

You can also click on **New** > **Model** > **Flow.**

<figure><img src="/files/tUScklYc29jv5hihXfsN" alt=""><figcaption></figcaption></figure>

You can then give your flow a name, and select if you want to start from scratch or from an existing  dataset.

If you choose to start from an existing dataset the flow created will contain the[ primary keys ](/data-management/workbench/understanding-datasets/primary-keys)and the [relationships](/data-management/workbench/understanding-datasets/relationships) of the base dataset.


# Update a Flow

You can modify a Flow query whenever you want to. In order to do so, click on your Flow and go to the **configuration** tab. You should be prompted with the **Flow Editor.**

<figure><img src="/files/dooD8zPVOTsIyH5o9o8L" alt=""><figcaption><p>Flow editor</p></figcaption></figure>

In the flow editor there are 5 kind of actions that you can do:

1. **Select a Step**\
   By clicking on any blocks in the editor you can view it's output as well as the configuration of the step, this is useful for debugging and understanding the overall creation process.
2. **Edit a Step**\
   When clicking on a step you can edit it in the left panel, each steps has its own configuration and some might not have any customisation capabilities. Please refer to the [Flow Steps](/data-management/workbench/model-data/flow-models/flow-steps) section to better understand what is available.
3. **Add a Step**\
   By clicking on any button in the action bar it will add a new step right after the selected one. If the selected one has already a next step the new step will be inserted in between the two existing steps.
4. **Set a Step as the Output**\
   A flow must have an output. The output doesn't have to be the last step in the Flow it could be any steps allowing you to continue working on your flow while not breaking its schema.
5. **Save the Flow Query**\
   Once you are done editing your Flow you can save it and the query will be updated right away.

### Understanding Steps

Steps have an internal state where they can be in <mark style="color:orange;">**warning**</mark> or in <mark style="color:green;">**success**</mark>. When your step configuration is not successful meaning that the SQL generated underneath contains errors then your step will be flagged as warning and a warning sign will be displayed next to it. When there is no warning sign it means that the steps is in success.&#x20;

<figure><img src="/files/WKGANpTgIenRaPx6jqhK" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Note that you cannot assign the output to a steps that has warnings and you cannot save your flow if any of the steps have warnings.
{% endhint %}

### Adding a Step

There are two ways of adding steps into the editor.&#x20;

If you want to add data then you can simply drag and drop data from your **View Selector** like you see below.&#x20;

<figure><img src="/files/l3Ldz2y3s36Ew5yaSoOX" alt=""><figcaption><p>Adding data</p></figcaption></figure>

If you want to add a step to modify data then you will need to click on the said step and add a new step by clicking on the toolbar and selecting the step you want to add.

<figure><img src="/files/tkiu8kZqbwq4WWQFZ9Ec" alt=""><figcaption><p>Adding a Step</p></figcaption></figure>

{% hint style="warning" %}
Column names must only contain alphanumeric characters and you must use underscores instead of spaces. Make sure your column does start by a letter. A column name must be unique on a dataset
{% endhint %}

### Removing a Step

You can remove a step by selecting it and clicking on the red cross at the top right hand corner of the step.

<figure><img src="/files/bKIm7stOhRG4GC8ZQCgD" alt=""><figcaption></figcaption></figure>

### Setting a Step as the output

You can set a step as the output by selecting a step and clicking on **set as output**

<figure><img src="/files/vENvd4hgKmSPXGGeeJd8" alt=""><figcaption><p><strong>Setting step as output</strong></p></figcaption></figure>


# Flow steps


# From Model

## What does it do?

It allows you to reference the output of another model in your Flow, bringing you composition capabilities without a headache.

## How to use it?

You simply use it by dragging and dropping any previously created **Model** (SQL or Flow) in the **View Selector.**

<figure><img src="/files/rehesJPex3M6QbcblPMR" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Note: A model cannot reference itself
{% endhint %}

## How to configure it?

There are no configuration option for this step.

## Rendered SQL

If the model is not materialized in your warehouse:

```sql
SELECT * FROM (<IMPORTED MODEL SQL>)
```

If the model is materialized in your warehouse as a view or a table we run:

```sql
SELECT * FROM database.schema.table
```


# From Raw

## What does it do?

It allows you to use raw data that is either imported from your warehouse or that has been replicated through sources.&#x20;

## How to use it?

You simply use it by dragging and dropping any imported **Datasets** (Third Party or Warehouse) in the **View Selector.**

<figure><img src="/files/jsuNGoxg5Rycqge4KnOg" alt=""><figcaption><p>Import data</p></figcaption></figure>

## How to configure it?

There are no configuration option for this step.

## Rendered SQL

We run:

```sql
SELECT * FROM database.schema.table
```


# Hide Column

## What does it do?

It allows you to select a subset of the columns to have a cleaner model.

## How to use it?

On any previously steps available in your editor select a step and click on **Hide Columns**

<figure><img src="/files/6ysrpDutZRYYVyxaoK1q" alt=""><figcaption><p>Hide columns</p></figcaption></figure>

## How to configure it?

<figure><img src="/files/ONzwpAKRjMhdEYDaGmQy" alt=""><figcaption></figcaption></figure>

You can use this highlighted panel to select the columns you want to keep and the columns you want to hide.


# Filter

## What does it do?

It allows you to filter rows from your model.

## How to use it?

On any previously steps available in your editor select a step and click on **Filter**

<figure><img src="/files/AeDbF4JkXtQ9es1LmKM2" alt=""><figcaption></figcaption></figure>

## How to configure it?

<figure><img src="/files/ibeMAGxHdb9xNbTS0wsX" alt=""><figcaption></figcaption></figure>

In order to use the filters you can:

* Modify the global condition from **ANY** to **ALL**
  * ANY means that if one condition is met then the line will be included in the results
  * ALL means that all conditions must be met for the line to be included in the results
* Apply condition to each lines by selecting a column, an operator and value. Depending on your column type, the available operator will change.
  * **STRING**&#x20;
  * **DATE**:
  * **NUMBERS**:
  * **BOOLEAN**:

### List of Available Operators

#### is set / is not set &#x20;

available for STRING / TIME / NUMERIC / BOOLEAN

expects no value

#### equals / does not equal

available for STRING / TIME / NUMERIC / BOOLEAN

expects one or more values

#### is in date range / is not in date range

available for TIME

expects one or more values

#### is before / is after

available for TIME

expects one or more values

#### is greater than

available for NUMERIC

expects one or more values

#### is greater or equal than

available for NUMERIC

expects one or more values

#### is lower than

available for NUMERIC

expects one or more values

#### is lower or equal than

available for NUMERIC

expects one or more values

#### contains

available for STRING

expects one or more values

#### does not contains

available for STRING

expects one or more values

When multiple values are inputed we expect the condition to match at least one of the values to return the line.


# Lookup

## What does it do?

Searches down a column of a dataset for a key and returns the value of a specified column in the row found. Think of it as the VLOOKUP from excel but at scale.

## How to use it?

In order to use the lookup step, click on the **Add Column** button and then **Lookup**&#x20;

<figure><img src="/files/q1qBNiTo8kxjLrPa6NPj" alt=""><figcaption><p><strong>Add a lookup</strong></p></figcaption></figure>

## How to configure it?

<figure><img src="/files/og7VOdSV6ccJF6lbkPV4" alt=""><figcaption><p>Configuring lookup</p></figcaption></figure>

To configure a lookup you need two datasets at least in your canvas. Select the dataset you want to lookup the value from in the dropdown (in order to help you locate the dataset on the canvas it must be blinking when hovered on the dropdown). Then select the column that will be the output of the lookup (the one you want the value to be displayed) and finally select the keys that will be used to identify how the lines should be merged.

In the example above we want to display the `campaign_id` value coming from another dataset under the name of  `new_campaign` on lines that matches `campaign_id` *=* `customer_id`


# Rollup

## What does it do?

Searches down a column of a dataset for a key and returns the selected aggregation of the value of a specified column in all rows found.

## How to use it?

In order to use the lookup step, click on the **Add Column** button and then **Rollup**&#x20;

<figure><img src="/files/HYIqVPk5I6OLzGT16buC" alt=""><figcaption><p>Add Rollup</p></figcaption></figure>

## How to configure it?

<figure><img src="/files/fFYwomlWcKeVotogytlV" alt=""><figcaption><p>Configuring Rollup</p></figcaption></figure>

To configure a roll you need two datasets at least in your canvas. Select the dataset you want to rollup the value from in the dropdown (in order to help you locate the dataset on the canvas it should be blinking when hovered on the dropdown). Then select the column that will be the output of the rollup as well as the aggregation type (the one you want the value to be displayed) and finally select the keys that will be used to identify how the lines should be merged.

In the example above we want to display the sum of`conversions`  coming from another dataset under the name of  `new_campaign` on lines that matches `campaign_id` *=* `customer_id`


# Formulas

## What does it do?

Creates a new column with the ouput of the formula.

## How to use it?

<figure><img src="/files/7jtM09A3IqTEkHA9YB8k" alt=""><figcaption></figcaption></figure>

## How to configure it?

<figure><img src="/files/9bVvnfmdu3bobt7aRNcq" alt=""><figcaption></figcaption></figure>

You can type any formula in the Formula text area. Available area are shown below.

## Available Formulas

#### IF(condition; expression\_if\_true; expression\_if\_false)

Takes three arguments, the first one must be a boolean and the second and third must return the same type.

In the `expression_if_true` and `expression_if_false` part, you can use **comparators** and **mathematical operations** such as: `+` ,`-` ,`/` ,`*` ,`>` ,`<` ,`=` ,`>=` ,`<=` ,`like`

Examples:

```
IF(column_a > column_b; "column_a is bigger than column_b"; "column_b is bigger than column_a")
IF(column_a + column_b <= 10; "Bigger than 10"; "less than 10")
IF(column_a like "%toto%"; "Toto detected"; "Toto is not here")
```

**Like operator**

The like operator is used to compare strings together and can be used to do "begins with", "ends with", "contains".

Begins with "toto": `column_a like "toto%"`

Ends with "toto": `column_a like "%toto"`

Contains "toto": `column_a like "%toto%"`

## URLs operators

#### UTM\_SOURCE(expression)

Takes an url as an input and return the utm source url parameter if exists or null.

```
UTM_SOURCE("https://whaly.io?utm_source=linkedin") => "linkedin"
```

#### UTM\_CAMPAIGN(expression)

Takes an url as an input and return the utm campaign url parameter if exists or null.

```
UTM_CAMPAIGN("https://whaly.io?utm_campaign=yc-announcement") => "yc-announcement"
```

#### UTM\_MEDIUM(expression)

Takes an url as an input and return the utm medium url parameter if exists or null.

```
UTM_MEDIUM("https://whaly.io?utm_medium=social") => "social"
```

#### UTM\_TERM(expression)

Takes an url as an input and return the utm term url parameter if exists or null.

```
UTM_TERM("https://whaly.io?utm_term=startup") => "startup"
```

#### UTM\_CONTENT(expression)

Takes an url as an input and return the utm content url parameter if exists or null.

```
UTM_CONTENT("https://whaly.io?utm_content=flavor_a") => "flavor_a"
```

#### DOMAIN(expression)

Takes an url as an input and return the domain of the url parameter if exists or null

```
DOMAIN("https://whaly.io?utm_content=flavor_a") => "whaly.io"
```

#### IS\_NULL(expression)

Takes a column as an input and returns a boolean. Return true if null or false if not null.

```
IS_NULL(null) => true
IS_NULL("ycombinator") => false
IS_NULL(0) => false
```

#### IS\_NOT\_NULL(expression)

Takes a column as an input and returns a boolean. Return true if not null or false if null.

```
IS_NOT_NULL(null) => false
IS_NOT_NULL("ycombinator") => true
IS_NOT_NULL(0) => true
```

**URL(url, label)**

Takes two column as an input and returns an html element that can be clicked on

```
URL("https://google.com"; "click me !")
```

## Date operators

#### NOW

Return the current time.

```
NOW => "2022-09-02"
```

#### DATEVALUE(expression)

Takes a number representing the number of milliseconds since the 1st January 1970 as an input and returns the associated date.

```
DATEVALUE(1630598507000) => "2021-09-02"
```

#### **DATEDIF(date1; date2; resultDateType)**

Returns the duration between date1 and date2 (date1 - date2), in Day, Month or Week.

```
DATEDIF("2021-02-01"; "2021-01-01"; "MONTH") => 1
DATEDIF("2021-02-01"; "2021-01-01"; "DAY") => 30
```

**resultDateType** can be: `MILLISECOND`, `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`.

#### **PARSE\_GOOGLESHEET\_TIMESTAMP(timestampColumn)**

Convert a Google Sheet timestamp (number of days since the 31th december 1899) into a proper date.

```
PARSE_GOOGLESHEET_TIMESTAMP(1) => "1899-12-31"
```

#### **COHORT(expression, Type)**

Returns a cohort when inputed a timestamp. Part can be: `DAY`, `WEEK` ,`MONTH` or `YEAR.`

```
COHORT("2018-12-19T12:00:00"; "DAY") => "2018-12-19T00:00:00"
COHORT("2018-12-19T12:00:00"; "WEEK") => "2018-12-17T00:00:00"
COHORT("2018-12-19T12:00:00"; "MONTH") => "2018-12-01T00:00:00"
COHORT("2018-12-19T12:00:00"; "YEAR") => "2018-01-01T00:00:00"
```

#### **COHORT\_WITH\_TZ(expression, Type, Timezone)**

Returns a cohort when inputed a date. Part can be: `DAY`, `WEEK` ,`MONTH` or `YEAR.`

Timezone will be used to calculate the proper DAY, WEEK, etc. in the Timezone. It should follow the Timezone [Database Name format](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), ex `Europe/Paris`

```
COHORT_WITH_TZ("2018-12-19T22:00:00"; "DAY"; "Europe/Paris") => "2018-12-20T00:00:00"
COHORT_WITH_TZ("2018-12-19T22:00:00"; "WEEK") => "2018-12-20T00:00:00"
COHORT_WITH_TZ("2018-12-19T22:00:00"; "MONTH") => "2018-12-01T00:00:00"
COHORT_WITH_TZ("2018-12-19T22:00:00"; "YEAR") => "2018-01-01T00:00:00"
```

#### DATEADD(Date; Interval; Part)

Add period to a date. Part can be: `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `QUARTER`, `YEAR`

```
DATE_ADD("2018-12-19"; 1; "DAY") => "2018-12-20"
DATE_ADD("2018-12-19"; 1; "YEAR") => "2019-12-19"
```

#### DATETIME\_FORMAT(expression; format)

Format a date into string. Supported format are described below.

```
DATETIME_FORMAT("2018-12-19"; "%A, %B %e, %Y") => "Wednesday, December 19, 2018"
DATETIME_FORMAT("2018-12-19"; "%B") => "December"
```

#### **DATETIME\_PARSE(expression; format)**

Parse a string that match the format and turn it into a Date. Supported format are described below.

```
DATETIME_PARSE("Wednesday, December 19, 2018"; "%A, %B %e, %Y") => "2018-12-19"
```

## Text operators

#### CONCAT(...expressions)

Takes several columns separated by "`;`" and returns a concatenated string. Ex:

```
CONCAT("Hello"; " "; "World") => "Hello World"
```

#### LEFT(string; howMany)

Extract howMany characters from the beginning of the string.

```
LEFT("quick brown fox"; 5) => "quick"
```

#### RIGHT(string; howMany)

Extract howMany characters from the end of the string.

```
RIGHT("quick brown fox"; 3) => "fox"
```

#### MID(string; whereToStart; count)

Extract a substring of count characters starting at whereToStart.

```
MID("quick brown fox"; 7; 5) => "brown"
```

#### LENGTH(string)

Count the number of characters in the String.

```
LENGTH("whaly") => 5
```

#### SPLIT(columnToBeSplitted; splitSeparator; indexToGet)

Split a column content according to a separator and then return the value at the given index in the splitted array.

```
SPLIT("CatA > CatB > CatC"; ">"; 1) => "CatB"
```

## **Logical operators**

#### **AND(expressionA; expressionB)**

Return true if expressionA ***and*** expressionB are true.

```
AND(true; true) => true
AND(true; false) => false
AND(false; false) => false
```

#### **OR(expressionA; expressionB)**

Return true if expressionA ***or*** expressionB are true.

```
OR(true; true) => true
OR(true; false) => true
OR(false; false) => false
```

## Number operators

#### **ROUND(expression; precision)**

Round a number with a precision.

```
ROUND(3.14; 0) => 3
ROUND(3.14; 1) => 3.1
ROUND(4.65; 1) => 4.7
```

#### FLOOR(expression)

Floor a number, get rid of the decimals.

```
FLOOR(3.14) => 3
FLOOR(3.1) => 3
FLOOR(3) => 3
```

#### VALUE(expression)

Convert a text into an integer number.

```
VALUE("3") => 3
VALUE("3.2") => 3
VALUE("Invalid") => null
```

## DATETIME formula format

Unless otherwise noted, `DATETIME` functions that use format strings support the following elements:

### When using BigQuery warehouse

| Format element | Description                                                                                                                                                                                                                                                                                                                                | Example                  |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ |
| %A             | The full weekday name.                                                                                                                                                                                                                                                                                                                     | Wednesday                |
| %a             | The abbreviated weekday name.                                                                                                                                                                                                                                                                                                              | Wed                      |
| %B             | The full month name.                                                                                                                                                                                                                                                                                                                       | January                  |
| %b or %h       | The abbreviated month name.                                                                                                                                                                                                                                                                                                                | Jan                      |
| %C             | The century (a year divided by 100 and truncated to an integer) as a decimal number (00-99).                                                                                                                                                                                                                                               | 20                       |
| %c             | The date and time representation.                                                                                                                                                                                                                                                                                                          | Wed Jan 20 21:47:00 2021 |
| %D             | The date in the format %m/%d/%y.                                                                                                                                                                                                                                                                                                           | 01/20/21                 |
| %d             | The day of the month as a decimal number (01-31).                                                                                                                                                                                                                                                                                          | 20                       |
| %e             | The day of month as a decimal number (1-31); single digits are preceded by a space.                                                                                                                                                                                                                                                        | 20                       |
| %F             | The date in the format %Y-%m-%d.                                                                                                                                                                                                                                                                                                           | 2021-01-20               |
| %G             | The [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) year with century as a decimal number. Each ISO year begins on the Monday before the first Thursday of the Gregorian calendar year. Note that %G and %Y may produce different results near Gregorian year boundaries, where the Gregorian year and ISO year can diverge.            | 2021                     |
| %g             | The [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) year without century as a decimal number (00-99). Each ISO year begins on the Monday before the first Thursday of the Gregorian calendar year. Note that %g and %y may produce different results near Gregorian year boundaries, where the Gregorian year and ISO year can diverge. | 21                       |
| %H             | The hour (24-hour clock) as a decimal number (00-23).                                                                                                                                                                                                                                                                                      | 21                       |
| %I             | The hour (12-hour clock) as a decimal number (01-12).                                                                                                                                                                                                                                                                                      | 09                       |
| %j             | The day of the year as a decimal number (001-366).                                                                                                                                                                                                                                                                                         | 020                      |
| %k             | The hour (24-hour clock) as a decimal number (0-23); single digits are preceded by a space.                                                                                                                                                                                                                                                | 21                       |
| %l             | The hour (12-hour clock) as a decimal number (1-12); single digits are preceded by a space.                                                                                                                                                                                                                                                | 9                        |
| %M             | The minute as a decimal number (00-59).                                                                                                                                                                                                                                                                                                    |                          |
| %m             | The month as a decimal number (01-12).                                                                                                                                                                                                                                                                                                     | 01                       |
| %n             | A newline character.                                                                                                                                                                                                                                                                                                                       |                          |
| %P             | Either am or pm.                                                                                                                                                                                                                                                                                                                           | pm                       |
| %p             | Either AM or PM.                                                                                                                                                                                                                                                                                                                           | PM                       |
| %Q             | The quarter as a decimal number (1-4).                                                                                                                                                                                                                                                                                                     | 1                        |
| %R             | The time in the format %H:%M.                                                                                                                                                                                                                                                                                                              | 21:47                    |
| %r             | The 12-hour clock time using AM/PM notation.                                                                                                                                                                                                                                                                                               | 09:47:00 PM              |
| %S             | The second as a decimal number (00-60).                                                                                                                                                                                                                                                                                                    | 00                       |
| %s             | The number of seconds since 1970-01-01 00:00:00. Always overrides all other format elements, independent of where %s appears in the string. If multiple %s elements appear, then the last one takes precedence.                                                                                                                            | 1611179220               |
| %T             | The time in the format %H:%M:%S.                                                                                                                                                                                                                                                                                                           | 21:47:00                 |
| %t             | A tab character.                                                                                                                                                                                                                                                                                                                           |                          |
| %U             | The week number of the year (Sunday as the first day of the week) as a decimal number (00-53).                                                                                                                                                                                                                                             | 03                       |
| %u             | The weekday (Monday as the first day of the week) as a decimal number (1-7).                                                                                                                                                                                                                                                               | 3                        |
| %V             | The [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date) week number of the year (Monday as the first day of the week) as a decimal number (01-53). If the week containing January 1 has four or more days in the new year, then it is week 1; otherwise it is week 53 of the previous year, and the next week is week 1.               | 03                       |
| %W             | The week number of the year (Monday as the first day of the week) as a decimal number (00-53).                                                                                                                                                                                                                                             | 03                       |
| %w             | The weekday (Sunday as the first day of the week) as a decimal number (0-6).                                                                                                                                                                                                                                                               | 3                        |
| %X             | The time representation in HH:MM:SS format.                                                                                                                                                                                                                                                                                                | 21:47:00                 |
| %x             | The date representation in MM/DD/YY format.                                                                                                                                                                                                                                                                                                | 01/20/21                 |
| %Y             | The year with century as a decimal number.                                                                                                                                                                                                                                                                                                 | 2021                     |
| %y             | The year without century as a decimal number (00-99), with an optional leading zero. Can be mixed with %C. If %C is not specified, years 00-68 are 2000s, while years 69-99 are 1900s.                                                                                                                                                     | 21                       |
| %%             | A single % character.                                                                                                                                                                                                                                                                                                                      | %                        |
| %E\<number>S   | Seconds with \<number> digits of fractional precision.                                                                                                                                                                                                                                                                                     | 00.000 for %E3S          |
| %E\*S          | Seconds with full fractional precision (a literal '\*').                                                                                                                                                                                                                                                                                   | 00.123456                |
| %E4Y           | Four-character years (0001 ... 9999). Note that %Y produces as many characters as it takes to fully render the year.                                                                                                                                                                                                                       | 2021                     |

### When using Snowflake Warehouse

| `YYYY`                       | Four-digit year.                                                                                                                                                                                                                                                        |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `YY`                         | Two-digit year, controlled by the [TWO\_DIGIT\_CENTURY\_START](https://docs.snowflake.com/en/sql-reference/parameters.html#label-two-digit-century-start) session parameter, e.g. when set to `1980`, values of `79` and `80` parsed as `2079` and `1980` respectively. |
| `MM`                         | Two-digit month (01=January, etc.).                                                                                                                                                                                                                                     |
| `MON`                        | Full or abbreviated month name.                                                                                                                                                                                                                                         |
| `MMMM`                       | Full month name.                                                                                                                                                                                                                                                        |
| `DD`                         | Two-digit day of month (01 through 31).                                                                                                                                                                                                                                 |
| `DY`                         | Abbreviated day of week.                                                                                                                                                                                                                                                |
| `HH24`                       | Two digits for hour (00 through 23). You must not specify `AM` / `PM`.                                                                                                                                                                                                  |
| `HH12`                       | Two digits for hour (01 through 12). You can specify `AM` / `PM`.                                                                                                                                                                                                       |
| `AM` , `PM`                  | Ante meridiem (am) / post meridiem (pm). Use this only with `HH12` (not with `HH24`).                                                                                                                                                                                   |
| `MI`                         | Two digits for minute (00 through 59).                                                                                                                                                                                                                                  |
| `SS`                         | Two digits for second (00 through 59).                                                                                                                                                                                                                                  |
| `FF[0-9]`                    | Fractional seconds with precision 0 (seconds) to 9 (nanoseconds), e.g. `FF`, `FF0`, `FF3`, `FF9`. Specifying `FF` is equivalent to `FF9` (nanoseconds).                                                                                                                 |
| `TZH:TZM` , `TZHTZM` , `TZH` | Time zone hour and minute, offset from UTC. Can be prefixed by `+`/`-` for sign.                                                                                                                                                                                        |


# Group

## What does it do?

It groups rows that have the same values into one group or bucket, and is used in conjunction with aggregate functions (`COUNT`, `SUM`, `MIN` or `MAX`) to output additional summary columns.

## How to use it ?

On any previously steps available in your editor select a step and click on **Group**

<figure><img src="/files/8G2Fin27LrZvvhvhSIDY" alt=""><figcaption></figcaption></figure>

## How to configure it ?

<figure><img src="/files/B4ZjmFbMiEZrTVjeVTbq" alt=""><figcaption></figcaption></figure>

#### Group on

In the group by form, start by selecting the columns you want to group on. The grouping will be applied as the unique values generated by the selected columns.

{% hint style="info" %}
Columns not used in the "grouped on" will not be available in the output of this step.
{% endhint %}

#### Aggregation (optional)

You can then optionally create as many aggregation as you need. An aggregation takes :&#x20;

* An operator (`COUNT`, `SUM`, `MIN` or `MAX)`
* A column to perform the aggregation on. The column must be of numerical type.
* A new column name for the aggregated data you will create.


# Union

## What does it do?

Union allows you to combine multiple datasets and models into one by matching the columns.

## How to use it ?

On any previously steps available in your editor select a step and click on **Combine -> Union**

<figure><img src="/files/sSo3cWmca97UprnyZx0Y" alt=""><figcaption></figcaption></figure>

## How to configure it ?

<figure><img src="/files/z6bQQNjUOYk27SWW7sQe" alt=""><figcaption></figcaption></figure>

#### Union

In the form, start by selecting the dataset or models with want to union. If you see an empty list, drop a dataset or a model from the left panel into the canvas.

#### Columns

Select the columns your union step will output.

{% hint style="info" %}
Only the columns that have the same name and type in the two steps will be available&#x20;
{% endhint %}


# Import raw data

There are two ways of importing raw data in Whaly. The first one is to use our [Sources](/connectors/how-sources-work), this will allow you to replicate raw data in near real time into your warehouse and so you create model and / or explorations on top of it. The second one is to import directly tables that are already stored into your warehouse into Whaly.

Learn how to import data:

{% content-ref url="/pages/XZp3v5JB6j5n58OstzBG" %}
[From your warehouse](/data-management/workbench/import-raw-data/from-your-warehouse)
{% endcontent-ref %}

{% content-ref url="/pages/fwAMsz2vIhTWC4JnfShj" %}
[From third party data](/data-management/workbench/import-raw-data/from-third-party-data)
{% endcontent-ref %}


# From your warehouse

## Why importing data from your warehouse

Importing existing tables and views that are already present in your Data Warehouse gives you a great freedom.

It's a great way to:

* Connect with other ETL/ELT systems that creates and feeds tables in your Warehouse ([Segment](https://segment.com/product/warehouses/), [Fivetran](https://fivetran.com/), [Stitch](https://www.stitchdata.com/), [Airbyte](https://airbyte.io/), [Hevo](https://hevodata.com/integrations/pipeline/?source=whaly), in-house connectors, ...)&#x20;
* &#x20;Expose models created with [dbt](https://www.getdbt.com/)
* Expose your ML/AI datasets (scoring, use of ML capabilities of your Warehouse, etc.)

## Import Table from your warehouse

In some case you already have created some tables in your data warehouse that you would like to use in Whaly to create exploration on top of it. To do so you can import raw tables directly into Whaly.  Click on the + button next to **Source** in the **Data Selector** and select **from warehouse**. You'll be prompted to select a name and an icon for your **Source.** A best practice, is to name your source with the name of the schema that you are importing so your users to feel lost.

<figure><img src="/files/dk5DPg2O22MvAsqrIIbH" alt=""><figcaption><p>Creating a source for import</p></figcaption></figure>

When your source is created you have the capability to import raw table. To do so click on your newly created source and then on **+ import dataset**. Your are now prompted with a wizard that will help you select:

* The **database** from which you want to import (in BigQuery it is always set as default as BigQuery doesn't have databases)
* The **schema** from which you want to import the tables
* A list of **tables** available in this schema

You can select as much **tables** as you want and click on next.

<figure><img src="/files/dGBS154jDpe5tpjv0ae6" alt=""><figcaption></figcaption></figure>

On the next screen you are prompted with a form that ask you to fill the **dataset** name as well as the **primary keys** so that the import might be finalized. you can click on save and voilà you have imported data from your own warehouse.&#x20;


# From third party data

In order to connect to new sources your can from the workbench click on the + button next to **Source** in the **Data Selector** and select **from third party**. You'll then be redirected to the source catalog where you can choose which source to connect.

<figure><img src="/files/s78BEMHFfyHpTDqn8naE" alt=""><figcaption><p>Connect a source</p></figcaption></figure>


# Explorations

This section helps you understand what explorations are and how you can use them to achieve your goals.

## What are explorations?

Exploration are a combinations of datasets, relationships and aggregations put together so that your data consumer can safely combine data and create reports without relying on technical expertise.

This help you:

* Boost data adoption by providing a product to your end users
* Make your user more data savvy by giving them tools they understand
* Maintain your company metric layer by controlling how data is being queried
* Reduce maintenance when definition change - when updating a metric or a dimension all reports are subsequently updated with your changes.

An exploration is the entry point to create charts in Whaly.


# Configure an exploration

To create an exploration, go to the workbench and in the tab bar click on exploration, thenat the top of page, click on the "+" sign, and click on create an exploration :&#x20;

![](/files/K5UKBpCBAY9TJkHNnLCx)

## Create an exploration from a template

Creating an exploration from a template is the easiest way to get started, as it will allow you to get an exploration with already defined measures, dimensions and related datasets.

To create an exploration from a template, go to the template catalog, select the template you want to use and then click on "Use this template". You will be redirected to the newly created exploration.

{% content-ref url="/pages/IcsbLgTuG0msdgldncJF" %}
[Exploration Templates](/data-management/explorations/exploration-templates)
{% endcontent-ref %}

## Create an exploration from scratch

Creating an exploration from scratch is useful if you want to explore some specific data or if you can't find a related template for your data.&#x20;

When creating an exploration from scratch, you will be asked to select the dataset you want to start your exploration from. You will be able to leverage the relationships declared in your workbench to add related data inside your exploration.&#x20;

{% hint style="info" %}
It's considered a good practice to start your exploration from the data you want to explore. For instance, if you want to count the number of contacts by their company geographic distribution, you would need to create an exploration based on contacts and add the companies afterwards as a related data.
{% endhint %}

## Updating an exploration

In order to update an exploration you can update all tables metrics and dimensions at once and when you are done you can then click on the save button. This will persist all your changed and you will be able to view your change in the exploration consumption screen.

<figure><img src="/files/jdpoGLQOazYZDIhLJLSt" alt=""><figcaption></figcaption></figure>


# Exploration Templates

Exploration templates are design to help you kickstart an exploration. It is based on raw data coming from Whaly's [sources](/connectors/how-sources-work) and will generate an exploration containing dimensions, metrics and related data, for you to get a quick view on how to use your raw data.

You can find all available exploration templates in the [Catalog](/workspace/catalog).


# Tables

Tables are what hold your measures ([dimension](/data-management/explorations/dimensions) & [metrics](/data-management/explorations/metrics)). They are based on a dataset that you have either [imported](/data-management/workbench/import-raw-data) or that you have [modeled](/data-management/workbench). They allow you to use the relationships that you have defined with all your models to add [related data](/data-management/explorations/tables/add-related-data) and create exploration that abstract the complexity of joins for your end users. An exploration must have at least one exploration.


# Configure a table

<figure><img src="/files/HHfm8dFKYcYV2X9a0ETs" alt=""><figcaption></figcaption></figure>

In order to configure a table you can click on one. Tables can be in error, when they do so, they are marked in red and a cross mark appears next to the table name. When hovering on the cross mark you can then view the reason of the error and correct it.

<figure><img src="/files/JlcAQz6p937IhiEqVXB8" alt=""><figcaption></figcaption></figure>

## Automatic measure creation

When creating a table for a new exploration or when adding related data we prompt you the choice of adding a raw table (without any metrics or dimension) and you can create your own metrics and dimensions, or we will create them for you.&#x20;

In the case where we create the metrics and dimensions for the newly created table, we will create for each column of type Numeric and is not called `id` or does not ends with `_id` create an `average` and a `sum` metric of the column, we will also create a `count` metric for the whole table. For all the other columns we will create a dimension. If your dataset has more than 200 columns we will throw an error.


# Add related data

Whenever you want to combine data from different datasets you can use related data. In order to do so, click on the "+" button and click on "add related data".

<figure><img src="/files/gcFljSPXltPBC7NJ84Hu" alt=""><figcaption><p>click on add related data</p></figcaption></figure>

Once you have done that, you should see a menu presenting you with all the dataset related to the one you have selected. We based related data on the relationships that have been created in the workbench between your datasets.

<figure><img src="/files/qIAFJKdqFavqQiz1n5xL" alt=""><figcaption><p>Adding related data</p></figcaption></figure>

Once you have clicked on the table you want to add you can automatically import all metrics and all dimension from your dataset. [Please refer to this section to understand how it works.](/data-management/explorations/tables/configure-a-table#automatic-measure-creation)


# Metrics

## What is a metric ?

A metric allows you to calculate things over your data.

For example, imagine that you go grocery shopping. If you count the number of tomatoes available in the store, then the "Number of tomato" is a metric. You could also calculate the average number of products in the shelves, which is also a metric.


# Create a Metric

To create a metric, simply click on the + sign next to the table name in the measure panel of the exploration screen, and click on add a metric. This will open the metric creation screen.&#x20;

<figure><img src="/files/5ShkgE4GXwMAPnqRLh0P" alt=""><figcaption><p>Add a new measure of data</p></figcaption></figure>

### Select an aggregation type

When creating a metric you must select an operation and a column to perform the aggregation on. Whaly supports the following aggregations:

<figure><img src="/files/d4nvKmz4rGT3TVqXYsTU" alt=""><figcaption><p>Select an aggregation</p></figcaption></figure>

<table><thead><tr><th width="242.87889314611186">Aggregation</th><th>Description</th></tr></thead><tbody><tr><td><h4>Count</h4></td><td>Count the number of line in your dataset. For instance counting the number of line of contacts will be the same as counting the number of contacts</td></tr><tr><td><h4>Count Distinct</h4></td><td>Allow you to select a specific field you want to get the number of distinct value from. For instance if you apply count distinct on the first name of the contact, you will get the number of different first name your contacts have. </td></tr><tr><td><h4>Sum, Median, Average, Min, Max</h4></td><td>Allow you to sum a column. Best applied to amounts or prices. For instance you can get your revenue by summing, averaging or getting the min or max of the amount of each deal in your pipeline. </td></tr><tr><td><strong>Cumulative Count</strong></td><td>Count function counts a number of items/records that satisfy the given criteria. The cumulative count function is the sum of all the counts generated so far.</td></tr><tr><td><strong>Cumulative Sum</strong></td><td>Sum function sums a specific field of items/records that satisfy the given criteria. The cumulative sum function is the sum of all the sums generated so far.</td></tr></tbody></table>

<figure><img src="/files/eqzKU4bDABD6lgbDHdlc" alt=""><figcaption><p>Filter your metric</p></figcaption></figure>

You can also add a filter to your metric in order precisely defined which lines should be included/excluded from your metric (for example, you could set a filter to product\_type equals vegetable to only count products that are vegetables)

### Format your metric

The next step will ask you to select a format for your metric. You can set a custom prefix or suffit (useful for currency, weight, ...), or you can take things a step further by [using the custom format](/data-management/explorations/metrics/using-custom-formatting) feature.

<figure><img src="/files/lCHc8NKaFdNu2or6a9ms" alt=""><figcaption><p>Format your metric</p></figcaption></figure>

### Give a name and description to your metric

Finally, you should give a name and a description to your metric. This is useful to keep your work clean and understandable for the viewers.

<figure><img src="/files/2JC4QhUTEcWlIThrg9um" alt=""><figcaption></figcaption></figure>

### Add drill down

You can also add a way for your user to explore further than the chart by adding drill down on your metric, please check the following section:

{% content-ref url="/pages/jb6gmVpMxMv9VHDyOZ9r" %}
[Create Drill Downs](/data-management/explorations/metrics/create-drill-downs)
{% endcontent-ref %}


# Create a Calculated Metric

A calculated metric is a metric that is based on other metrics, numbers and operators. When creating a calculated metric, you are presented with a formula editor. For example, let's say that we want to create a metric which is the percentage of gift card payment on a website. We already have two metrics : the total payment on our website and the payments with gift card on our website. Then, our calculated metric would look like the following :&#x20;

<figure><img src="/files/ZtWhKXDHoUmsmF1pmCOv" alt=""><figcaption></figcaption></figure>

### Format your metric

The next step will ask you to select a format for your metric. You can set a custom prefix or suffit (useful for currency, weight, ...), or you can take things a step further by [using the custom format](/data-management/explorations/metrics/using-custom-formatting) feature.

### Add drill down

You can also add a way for your user to explore further than the chart by adding drill down on your metric, please check the following section:

{% content-ref url="/pages/jb6gmVpMxMv9VHDyOZ9r" %}
[Create Drill Downs](/data-management/explorations/metrics/create-drill-downs)
{% endcontent-ref %}


# Create Drill Downs

Drills downs are used by data consumers to explore further a metric. They will be available when the user clicks on the chart and will show the underlying records that have been used to compute the metric.

Drill downs can be defined at the table level or at the metric level. Metric will inherit for the table configuration and can override the table configuration if needed.&#x20;

### Configuring Drill Downs at the table level

<figure><img src="/files/SpkhW2uheEt5tYii8XVn" alt=""><figcaption><p>Drill at the table level</p></figcaption></figure>

&#x20;At the table level drill downs can be:

* **Disabled** by default: This means that end users won't be able to click on the chart to get access to the records.
* **Inherit** from the dataset configuration (default): [On the dataset](/data-management/workbench/understanding-datasets/drills) that is used to build the table you can define columns that will be used on all metrics
* Use a **combination of dimension and metric**: You can generate your own query with your own dimension and metrics to make the drills more readable

By default all metrics created under this table will inherit the table configuration

### Configuring Drill Downs at the metric level

<figure><img src="/files/H6OfKzjK5iYLyo72oef7" alt=""><figcaption><p>Configuring drills at the metric level</p></figcaption></figure>

At the metric level drill downs can be:

* **Disabled:** If for some reason you want to avoid your users to view records on a specific metric, this can be useful for calculated metrics  as record level is not easily understandable.
* **Inherit from table (default):** This will give you the drills that are configured at the table level
* **Select from existing measure**: You can generate any query you wish at the metric level


# Using custom formatting

## Formatting numbers

Custom number format relies on [numeral.js](http://numeraljs.com/#format) in order to provide you with the ability to easily customise your metrics formatting.

The following table should be read this way:

* Number is an example number
* Format is the format you should type in the custom format input on Whaly
* Output show how your metric will display using the custom format

**Numbers formats**

| Number     | Format     | Output        |
| ---------- | ---------- | ------------- |
| 10000      | 0,0.0000   | 10,000.0000   |
| 10000.23   | 0,0        | 10,000        |
| 10000.23   | +0,0       | +10,000       |
| -10000     | 0,0.0      | -10,000.0     |
| 10000.1234 | 0.000      | 10000.123     |
| 100.1234   | 00000      | 00100         |
| 1000.1234  | 000000,0   | 001,000       |
| 10         | 000.00     | 010.00        |
| 10000.1234 | 0\[.]00000 | 10000.12340   |
| -10000     | (0,0.0000) | (10,000.0000) |
| -0.23      | .00        | -.23          |
| -0.23      | (.00)      | (.23)         |
| 0.23       | 0.00000    | 0.23000       |
| 0.23       | 0.0\[0000] | 0.23          |
| 1230974    | 0.0a       | 1.2m          |
| 1460       | 0 a        | 1 k           |
| -104000    | 0a         | -104k         |
| 1          | 0o         | 1st           |
| 100        | 0o         | 100th         |

**Currency formats**

| Number    | Format      | Output     |
| --------- | ----------- | ---------- |
| 1000.234  | $0,0.00     | $1,000.23  |
| 1000.2    | 0,0\[.]00 $ | 1,000.20 $ |
| 1001      | $ 0,0\[.]00 | $ 1,001    |
| -1000.234 | ($0,0)      | ($1,000)   |
| -1000.234 | $0.00       | -$1000.23  |
| 1230974   | ($ 0.00 a)  | $ 1.23 m   |

**Bytes formats**

| Number        | Format   | Output    |
| ------------- | -------- | --------- |
| 100           | 0b       | 100B      |
| 1024          | 0b       | 1KB       |
| 2048          | 0 ib     | 2 KiB     |
| 3072          | 0.0 b    | 3.1 KB    |
| 7884486213    | 0.00b    | 7.88GB    |
| 3467479682787 | 0.000 ib | 3.154 TiB |

**Percentages formats**

| Number      | Format    | Output   |
| ----------- | --------- | -------- |
| 1           | 0%        | 100%     |
| 0.974878234 | 0.000%    | 97.488%  |
| -0.43       | 0 %       | -43 %    |
| 0.43        | (0.000 %) | 43.000 % |

**Time formats**

| Number | Format   | Output   |
| ------ | -------- | -------- |
| 25     | 00:00:00 | 0:00:25  |
| 238    | 00:00:00 | 0:03:58  |
| 63846  | 00:00:00 | 17:44:06 |

**Exponential formats**

| Number       | Format   | Output   |
| ------------ | -------- | -------- |
| 1123456789   | 0,0e+0   | 1e+9     |
| 12398734.202 | 0.00e+0  | 1.24e+7  |
| 0.000123987  | 0.000e+0 | 1.240e-4 |

## Formatting durations

Custom duration format relies on [moment duration format](https://github.com/jsmreese/moment-duration-format) in order to provide you with the ability to easily customise your metrics formatting.

To format a duration you can use the following tokens :&#x20;

| Category     | Token | Output       |
| ------------ | ----- | ------------ |
| milliseconds | S     | 1 2 3 ...    |
|              | SS    | 01 02 03 ... |
| seconds      | s     | 1 2 3 ...    |
|              | ss    | 01 02 03 ... |
| minutes      | m     | 1 2 3 ...    |
|              | mm    | 01 02 03 ... |
| hours        | h     | 1 2 3 ...    |
|              | hh    | 01 02 03 ... |
| days         | d     | 1 2 3 ...    |
|              | dd    | 01 02 03 ... |
| weeks        | w     | 1 2 3 ...    |
|              | ww    | 01 02 03 ... |
| months       | M     | 1 2 3 ...    |
|              | MM    | 01 02 03 ... |
| years        | y     | 1 2 3 ...    |
|              | yy    | 01 02 03 ... |

Escape token characters within the template string using square brackets.

### Examples&#x20;

| Input (in seconds) | format               | output         |
| ------------------ | -------------------- | -------------- |
| 61                 | mm:ss                | 01:01          |
| 61                 | m \[min], s \[sec]   | 1 min, 1 sec   |
| 61                 | mm \[min], ss \[sec] | 01 min, 01 sec |


# Dimensions

## What is a dimension ?

A dimension allows you to categorise your data. For example, imagine that you go grocery shopping (again!). We are buying tomato, so we can probably group our tomatoes by size, by color, by weight, and so on. These are dimensions, are they allow use to put our tomatoes into different groups.&#x20;


# Create a dimension

In order to view our data, we will create a first dimension. In order to do so, click on the "+ " next to contact in the measure section and click on "add a dimension".

<figure><img src="/files/lseteaFXFTlF0tVSEpXl" alt=""><figcaption><p>Creating a dimension</p></figcaption></figure>

### Select an dimension type

When creating a dimension you must select a type. Whaly supports the following type:

* Standard : to create categories (such as name, color, ...)
* Geolocation : to create location dimensions based on two columns, latitude and longitude

### Select the column(s)

Select the columns you need for your dimension

### Give a name and description to your dimension

Finally, you should give a name and a description to your dimension. This is useful to keep your work clean and understandable for the viewers.

Click on save. There you go you have created your dimension.

{% hint style="info" %}
Don't forget that dimensions are like labels, so they work best when the number of values is relatively low (few dozens rather than few hundreds)
{% endhint %}


# Check measure usage

When hovering on any dimension or metric, you can check if it is already used in any reports or question.&#x20;

<figure><img src="/files/Lj8wWEkns2DfaPyrq0Kt" alt=""><figcaption><p>Check measure usage</p></figcaption></figure>

When a metric or a dimension is already in use we will display an arrow next to its name and an alert explaining where it is used. You can still delete it but you should be aware that this cannot be undone and that it might break the reports that are using this measure.


# Row Level Access

Row Level Access (RLA) allows Builders to control which rows of data each user can access, based on specific attributes configured at the user level. This ensures that users only see data relevant to their role, location, or other designated criteria. The feature enhances data security and personalization by filtering data dynamically per user.

Row Level Access is configured at the "Exploration" level. RLA binds a specific dimension within an [Exploration](/data-management/explorations) (e.g., "Country") to a [User Attribute](/user-management/user-attributes), allowing for granular control over the data a user can see in that context.

To implement RLA, you bind a dimension in the [Exploration](/data-management/explorations) to a [User Attribute](/user-management/user-attributes). A dimension is a field in the dataset, such as "Country," "Department," or "Team." The [User Attribute](/user-management/user-attributes) is configured at the user level and determines what value the user has for that dimension. For example, if the "Country" dimension is bound to a User Attribute "user\_country," users will only see rows where the "Country" matches their "user\_country" value.

Example:

* **Dimension:** Country
* **User Attribute:** user\_country
* **Outcome:** A user with "user\_country = USA" will only see rows where "Country = USA."

<figure><img src="/files/Ro5PY5StoRyYrVNZAWBN" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/OaM13NaZZh1op2jEyFgY" alt=""><figcaption></figcaption></figure>

### **FAQs**

#### **Q1: How do I troubleshoot RLA configuration issues?**

Ensure that the correct [User Attributes](/user-management/user-attributes) are assigned to users and that the dimension in the Exploration is properly bound to the User Attribute. Check that users have the necessary attribute values set. You can use [User Impersonation](/team/impersonate) to validate the setup.

#### **Q2: What happens if a user doesn’t have a User Attribute set?**

#### If a User Attribute is not set, the user will see no data for security reasons. So it's important to properly configure the [User Attribute](/user-management/user-attributes) of each users.

#### **Q3: I want some users to see all available data**

The `*` value can be used in [User Attribute](/user-management/user-attributes) value to indicate that the user can see everything.


# Exploring data

As a data consumer, sometimes dashboards and questions are not giving you the insight you are looking for. In order to explore data further that dashboards, your builder have setup explorations that will allow you to:

* Better understand how a chart has been created
* Find deeper insights than what's on the dashboard

Learn:

{% content-ref url="/pages/eeb9Qacx1sD27dguR6lc" %}
[How to explore data](/data-consumption/exploring-data/how-to-explore-data)
{% endcontent-ref %}

{% content-ref url="/pages/vYcVSFcUoAeeNIsImNXW" %}
[Chart your data](/data-visualisation/chart-your-data)
{% endcontent-ref %}

{% content-ref url="/pages/3hXNw9scgPEhCdm3AyK7" %}
[Forecasting](/data-consumption/exploring-data/forecasting)
{% endcontent-ref %}


# How to explore data

## Explore from your workspace

From your workspace tab, you can access all exploration your builders have created for you. In order to access all explorations from your workspace, click on **Explore** at the top of the [Content Selector](/workspace/workspace). Please note that only [editor](/organisation/manage-access-control#editor) and [higher roles](/organisation/manage-access-control#builder) have access to explorations.

<figure><img src="/files/S07TjV0p6UKP5yhXQLET" alt=""><figcaption><p>Explore from workspace</p></figcaption></figure>

## Exploring from Report

From a question or a dashboard you can **hover the tile** to click on the **three dots** and click on the **Explore from here** menu. This will open the query in exploration mode allowing you to dig deeper into your analysis. Please note that when you are exploring data you are NOT modifying the query of the chart making it safe for your user to explore without breaking anything.

<figure><img src="/files/hTCpi5UDDfpyG1I2ahiL" alt=""><figcaption></figcaption></figure>

## Using explorations

The exploration page is divided into three main panels:

* The measures panel
* The visualisation panel
* The options panel

![](/files/lV5CvEmpAJvuH2XuAO9l)

### Measures panel

The measure panel, on the left, contains your data tables, as well as their metrics and dimensions. In this panel, you can see the parent data table at the top level. On the exemple above, we can see that the exploration start from the Order table, and that we have added our order and our customer tables as related data.

We can also see multiple metrics (in blue) and dimensions (in green).

### Visualisation panel

The central panel, at the center, is divided into two groups:&#x20;

* First is the query builder, where you use metrics and dimensions in order to ask a question about your data.
* Then, under the "run query" button, you can see the actual visualisation which is the graphical representation of your query as defined in the query builder.

### Options panel

The options panel contains all styling options related to your current chart, for example you can show or hide labels, customise your series names and colors, ...


# Drill Down

On any report, users can drill through any chart. They can click on any figures to [access predefined values](/data-management/workbench/understanding-datasets/drills) by [your builder](/organisation/manage-access-control#builder).

Once the drills is shown you can download the results as CSV.

<figure><img src="/files/NZVmCjQg7xUFgvYWnxgW" alt=""><figcaption><p>Drills</p></figcaption></figure>

{% hint style="warning" %}
Please note that we are only showing 10000 results max per drills
{% endhint %}


# Forecasting

Forecasting allow you to predict a value in the future based on past data. It uses machine learning techniques to output the probable future.

## How to create a forecast

The forecast capability only works on timeseries chart that don't have a dimension grouping. When the capability is available it is materialized by a Create Forecast button in the chart area as shown below.

![Forecast button](/files/ruzHVAWSBQIABTFtRXyK)

When clicking on the button we will compute the next probable value based on the value that are displayed on the chart, therefore the more value are displayed on your chart the more accurate the forecast will be. We will forecast 10% of the number of steps that are used in your chart or a minimum or 1 value. For instance if your displaying a single value every day for a month we will predict 3 steps forward (30 days \* 10% = 3 days). If you display a week of values we will forecast 1 day (7 days \* 10% = 0.7 days rounded to 1).&#x20;

![Forecasted value](/files/qwyuTyWkelArN08Fk6OZ)

When you create your forecast you can see the probable value as well as the upper bound and lower bound for the forecasting.

## How does it work

We use under the hood [ARIMA](https://www.machinelearningplus.com/time-series/arima-model-time-series-forecasting-python/) to predict the future values of your time series. This is a state of the art algorithm that is used in production by multiple companies.


# What is a Report?

A report is a way of presenting data to end users.&#x20;

In Whaly reports can be&#x20;

* Dashboards - A combination of charts on the same page that tell a distinctive story
* Questions - A single chart that answers a specific questions

Learn how to create:

{% content-ref url="/pages/rw4wDokjYz2zFjzp5FD3" %}
[Dashboards](/data-consumption/dashboards)
{% endcontent-ref %}

{% content-ref url="/pages/XLekAAyr3zhomQDHoFmK" %}
[Questions](/data-consumption/questions)
{% endcontent-ref %}


# Dashboards

Dashboards allow you to combine charts together to answer business questions. You can share these reports with your colleagues or externally in your apps or publicly

## What is a dashboard ?

A dashboard is a page containing multiple charts (charts can be a table, a bar chart, a funnel, a map, ...). Usually, a dashboard will contain multiple charts related to the same topic, or answering different parts of the same question.&#x20;

A dashboard can be shared internally with your team on Whaly, on externally with your customers or business partners, either:&#x20;

* In a passive way by using a sharing link
* In a proactive way by using pushes to share your report in Slack or via Email

You can make your dashboards interactive by adding filters on a dashboard. These filter will be available for the users and will filter data in the same way on all your configured tiles.&#x20;


# Create a dashboard

## How to create a dashboard

There is two ways to create a report:&#x20;

* From a workspace folder
* From an exploration

### Creating a report from a workspace folder

To create a report from a folder, go to the folder you want to add the report to, then click on "Create a new report" button&#x20;

![](/files/zGAQS0ddBnUVgJhoZPlF)

### Creating a report from an exploration

To create a report from an exploration, go to an exploration, create a chart, then click on the "Save" button. Then, select "Add to report".

You will need to give a name to your chart, then, select the folder you want to create the report in, and click on "Add new" next to the report icon. Give a name to your report and click on save.

![](/files/7kcy040NExp1Q00N7f0B)


# Manage tiles

In this section we will see how to add tiles to a dashboard, and how to arrange tiles to structure our dashboard.

{% content-ref url="/pages/biTB7Zl8OURyC7wt501S" %}
[Add chart tiles](/data-consumption/dashboards/manage-tiles/add-chart-tiles)
{% endcontent-ref %}

{% content-ref url="/pages/J2iaRXcTlFh4sCntsc8k" %}
[Add text tiles](/data-consumption/dashboards/manage-tiles/add-text-tiles)
{% endcontent-ref %}

{% content-ref url="/pages/hpXWp95yY7OBpGjVkX3y" %}
[Add navigation tiles](/data-consumption/dashboards/manage-tiles/add-navigation-tiles)
{% endcontent-ref %}

{% content-ref url="/pages/VAQUwRBgJ2ZtjNOx3nHA" %}
[Arranging tiles](/data-consumption/dashboards/manage-tiles/arranging-tiles)
{% endcontent-ref %}


# Add chart tiles

There are two ways to add a chart to a dashboard:

* From an existing chart if you want to copy a chart
* From an exploration if you want to add a new chart

## From an existing chart

If you want to add an existing chart to a dashboard, browse to the chart you want to add, then click on the ⋮ -> explore from here. In the drawer that opens, click on the button "Add to report", then select the report you want to add the chart to:&#x20;

![](/files/j0SSX0OoPbwQDURPGhhK)

## From an exploration

On an exploration page, create a chart, then click on the "Save" button, then "Add to report":&#x20;

![](/files/1JmvO2L6zHZNtuagM65w)

{% hint style="info" %}
When editing a report, you can also quickly open an exploration by clicking on the visualisation button in the report action bar
{% endhint %}


# Add text tiles

You can add text tiles to a report to give some context to a dashboard, add explanations or even better structure your dashboards.

## Create a text tile

To add a text tile to a dashboard, create a new report (or edit an existing one) then click on the "Text" button in the action bar. Type your text, use the formatting options and click on create:&#x20;

![](/files/sQlbgS3oicvWxWqbqsJR)


# Add navigation tiles

Navigation tiles allow you to add buttons to a report. These buttons can link to other reports or to external links on the web.

## Create a navigation tile

To add a navigation tile to a dashboard, create a new report (or edit an existing one) then click on the "Add navigation" button in the action bar. Input the name of your navigation button in the popin and click on create.&#x20;

Then, select the tile that's just been created and edit its options:&#x20;

![](/files/bBxg6D0ul0ztwXYUEtd3)


# Arranging tiles

When in edit mode, it's easy to :&#x20;

* **Move a tile:** click on the tile you want to move and drag it across your report. Drop it where you want, the others tiles will automatically move out of the way.
* **Resize a tile:** click on the tile you want to resize then use the handle in the bottom right corner.&#x20;
* **Delete a tile**: click on the “⋮” button on the tile you want to delete then click on delete tile. :warning: This action can not be undone.


# Add a description

When building reports for others to consume, it's important to give as much context and explanations as possible. You can use the report description in order to inform users about your report.

To add a description, browse to the report you want, click on the "i" icon in the top bar and add your description:&#x20;

![](/files/aXFizMpBnNNvo3KyH7tJ)


# Share a dashboard

Sharing a dashboard with people inside or outside your organization is done with the **Sharing & Collaboration** tools of your workspace. [Read the article here](/workspace/sharing-and-collaboration).


# Filter a dashboard

In some situation you might want to create slight variations of the same report, for example to change the observed period or the current customer.&#x20;

Instead of creating multiple reports, you can create reports filters to let people filter the data displayed through the tiles of a report.&#x20;

This makes your reports more interactive to end users.

## Adding a filter

To add a filter on a report:

1. Click on the "E**dit**" button in the top right corner
2. Click on "**Add a filter**" button

In the modal that opens, set your filter settings:&#x20;

1. Select the dimension you want to filter on
2. Set a name for your filter
3. Click on create

<figure><img src="/files/zNs0ZeI4sGVgcwXK4Nu8" alt=""><figcaption></figcaption></figure>

## Updating a filter settings

Filters can be customised in a lot of ways in order to make your dashboard more interactive

<figure><img src="/files/SjgDjpQN7w0cIqRYiEES" alt=""><figcaption><p>In edit mode, filters settings are displayed when selecting a filter</p></figcaption></figure>

### Filter settings

* **Name**: the display name of the filter
* **Dimension**: which dimension the filter is based on. When selecting "default time field", the filter will automatically filter charts on their dimension selected as the time.
* **Display filter**: select if you want to hide the filter from the report, preventing users to update the filter value. It is useful when used with [sharing links](/workspace/sharing-and-collaboration/share-a-report-by-link) or with [user attributes](/user-management/user-attributes), in order to give a different default value to a filter based on the sharing link or on the user viewing the dashboard.

### Render options

Render options will be different when the filter is based on a date dimension or not.

#### For time dimensions

* **Defaults to**: can be set to predefined value to select a dimension or user attributes to select the value of a user attribute
* **Default value**: the filter default value

#### For other types of dimensions

* **Filter value**: the displayed dimension value of the filter. Is is used when you want the filter to filter on an id but to display a label instead
* **Filter type**: single value or multiple values
* **Requires a value**: can be set when filter type is "single value"
* **Defaults to**: can be set to predefined value to select a dimension or user attributes to select the value of a user attribute
* **Default value**: the filter default value
* **Autocomplete limit**: set the limit for the number of autocomplete values to fetch. Min is 0, max is 50'000, defaults to 5'000

### Tiles to update

Select wether a filter should update a specific chart, and on which dimension to apply the filter

### Controlled by

Manage filters that should restrict the autocomplete values of this filter

<figure><img src="/files/yWDmpiXsXPE5ICYOyKz6" alt=""><figcaption></figcaption></figure>

### **Developer Settings**

You can give an api name to your filter so you can control its value when using the report in [embedded](/embedding/embedding-api#access-your-filters-api-name) mode.

## Ordering filter

It's possible to order a filter on a dashboard in edit mode by drag and dropping them&#x20;

<figure><img src="/files/zbSMy7pwOpxAk5Ra8FWN" alt=""><figcaption></figcaption></figure>




---

[Next Page](/llms-full.txt/1)

