At the core of Tableau is data - your data. Your data can come in different formats and structures, categorized at varying levels of detail, and can have relationships with other data. This is the kind of metadata that you can expect to surface from the Metadata API using GraphQL.
To successfully create effective GraphQL queries, you need to understand how Tableau interprets and interacts with content and assets. Understanding this can inform the most efficient way for you to access metadata at the level of detail that you need.
Because the Metadata API uses GraphQL, this section describes the fundamental objects that are available to you to use in a GraphQL query.
In this section
The Metadata API surfaces the content and assets that comprise your Tableau Cloud site or Tableau Server, the content and asset roles, and how the content and assets relate to each other.
General Tableau content
Tableau content is unique to the Tableau platform. Content includes the following:
Tableau Cloud and Tableau Server specific content
Tableau content that can only be managed through Tableau Cloud or Tableau Server includes the following:
Note: Some content listed above can be managed through the Tableau REST API as well.
External assets associated with Tableau content
The Metadata API treats information about any data that comes from outside of the Tableau environment as external assets. External assets include the following:
Note: Cubes are not supported.
The GraphQL schema used by the Metadata API organizes content and assets on Tableau Cloud and Tableau Server by grouping them by object and role. These objects and their roles are the foundation to your GraphQL queries.
Parent objects, a mix of both content and assets, can be managed independently of other objects and play the role of a container. Parent objects can refer to other parent objects, can refer to child objects, and can also own child objects.
Parent objects
Child objects, also a mix of both content and assets, cannot be managed independently of their parent object. Therefore, child objects play a dependent role on their parent object.
Some child objects can own other child objects, can refer to other child objects, and in some cases, refer to certain parent objects.
Child objects
The GraphQL schema defines the parent/child object relationship by what the objects can contain. In other words, an object is a parent object when it functions as a container for other (child) objects. Some examples of such relationships are below.
Parallel to parent/child object role and relationship, the GraphQL schema organizes objects by object type and the attributes that it can inherit from the object.
To do this, objects are implemented in the GraphQL schema using “interfaces.” From each interface, object types inherit attributes and properties. This means that the object types that have the same interface have a logical association with each other and share common attributes and properties. In addition to the shared attributes and properties, object types can also have unique attributes and properties.
Examples of object types and their inherited attributes
The table below captures example objects, object types (interface), and their common and unique attributes and properties.
Object | Object type or interface | Common attributes and properties | Unique attributes and properties |
---|---|---|---|
Database |
|
|
CloudFile
|
Table |
|
|
CustomSQLTable
|
Datasource |
|
|
PublishedDataSource
|
Warnable (data quality warning) |
|
|
- |
Lineage shortcut objects
The Metadata API enables you to see relationships between the content and asset that you’re evaluating with other items on your Tableau Cloud site or Tableau Server. These items include the following:
You can quickly access this type of information by using shortcut objects defined in the GraphQL schema. These lineage or relationship objects use the upstream or downstream prefix. For example, you can use upstreamTablesConnection
to query the tables used by a data source, use downstreamSheetsConnection
to query sheets used by a workbook, or upstreamLinkedFlows
and downstreamLinkedFlows
to query flows that are directly upstream or downstream of one another.
For an example query that uses lineage shortcut, see Filtering section in the Example Queries topic. For more information about linked flows, see Working with linked flow objects below.
Pagination objects
The Metadata API enables you to traverse through relationships within the data that you’re querying using pagination. The GraphQL schema defines pagination objects as those objects that use the Connection suffix. For example, you can use the databasesConnection
to get a list of paginated results of database assets on your Tableau Cloud site or Tableau Server.
For an example query that uses pagination, see Pagination section in the Example Queries topic.
Inherited objects
You can query description attributes of fields using the Metadata API. These description attributes can be inherited from other upstream objects. For example, a field attribute can be inherited from an upstream column in a table or from an upstream data source authored in Tableau Desktop. Beginning in version 2021.2, you can include a description inheritance object, descriptionInherited
, in your query to return supplemental description information inherited from the closest upstream object.
For an example query that uses the description inheritance object, see Inheritance section in the Examples Queries topic.
Together, all objects, the roles they play, the relationships they have with each other and their attributes and properties define the metadata model for a particular set of objects. The metadata model is a snapshot (or in GraphQL terms, a graph) of how Tableau interprets and relates a set of objects on your Tableau Cloud site or Tableau Server. From the metadata model, you can understand the dependencies and relationships in your data.
To see how the metadata model used by the Metadata API works, review the following example scenarios.
Suppose you have three workbooks (parent objects) and two data sources (parent objects) published to Tableau Cloud or Tableau Server.
For this scenario, the two published data source objects refer to the three workbook objects. The workbook objects own four sheet objects. These sheet objects in turn refer to two field objects that are owned by the published data source objects.
Here’s what the metadata model for this scenario might look like.
Notes:
In an impact analysis scenario, the metadata model can help you answer how data might be affected if a part of the metadata model changes.
In this scenario, you might want to know what could happen if the published data source, John County - 1, is deleted.
As you know now from the metadata model, sheet objects are owned by workbook objects, and sheet objects can refer to the field objects. In this scenario, the field objects are owned by the published data source objects. Published data source objects own field objects. Therefore, if John County - 1 is deleted, the child objects, F1, Hills Library, and Garden Library, are directly affected and their existence compromised because of their dependency on that data source object. The other child objects, F2, Garden Senior Center, and Cliff Senior Center, though they might be affected by the data source object being deleted, their existence is not compromised.
During this analysis, you can see that because John County - 1 doesn’t own the workbook objects that connect to it, the workbook objects themselves, both Sakura District and Maple District can continue to exist in the absence of the published data source object.
In a lineage flow analysis scenario, you can look at particular part of the metadata model and identify where the data is coming from and how the data reacts or is affected by different parts of the metadata model.
In this scenario, you might want to know where a data point from a sheet object, Garden Senior Center, in a workbook object, Maple District, is coming from.
Based on what you know from the metadata model, attributes are inherited from the parent object . Therefore, if you start from Garden Senior Center sheet object, you can move to the referring field object, F2, to see that it’s owned by a published data source object. In this case, John County - 2 is the source for the data point.
During this analysis, you are able to freely include or exclude parts of the metadata model in order to understand the lineage flow for Garden Senior Center. For example, you can choose to exclude Garden Library sheet object even though it’s also owned by the same workbook object, Maple District.
Using custom SQL
The metadata model interprets customSQL queries as tables.
When custom SQL queries are defined in your data source or flow, the queries have to fit a set of criteria to be recognized and interpreted by the Metadata API. For more information, see Tableau Catalog support for custom SQL in the Tableau Help.
For programmatic methods to determine if the custom SQL used in a data source or flow is unsupported, see the isUnsupportedCustomSql and containsUnsupportedCustomSql booleans in the API reference.
Using the databaseTable object in a query
When you run a query using the databaseTable object, for some databases, the schema attribute might not return the correct schema name for the table. This issue can occur when the selected schema, while creating or editing a data source, workbook, or flow, is changed after adding the table.
When the selected schema changes after adding the table, the schema attribute your query returns is the name of the last selected schema instead of the actual schema that the table is using.
Databases that might return the incorrect schema in the scenario described above include Amazon Athena and Exasol.
When workbook lineage query results are missing upstream databases
When you run a lineage query to determine upstream databases (D1 and D2) from a workbook (WB), only the databases (D1) whose fields (F1) are used in a workbook’s sheet (S) are returned. Databases (D2) that might be referenced by the workbook, but whose fields aren’t used by a sheet directly, won’t show as upstream.
Unless you’re a Tableau Cloud site or Tableau Server admin, by default, results from a tags query that uses the asset attribute are obfuscated to block all sensitive data. Results are always obfuscated, whether you have the appropriate permissions to see the associated object’s metadata or not. To see the associated object’s metadata that you have the appropriate permissions to see, you can replace the asset attribute with a type-specific attribute instead.
For example, suppose you have permissions to see WorkbookA. You run the following tags query, which uses the asset attribute to return all objects that use tags.
{
tags {
assets {
id
name
}
}
}
In this example, the query returns two workbooks with its results obfuscated.
{
tags {
assets {
{ id: "A", name: null }
{ id: "B", name: null }
}
}
}
Because results are always obfuscated when you use the asset attribute in a tags query, you can modify the query to be type specific to return the results you expect. In this example, you can run a query using the workbook type instead.
{
tags {
workbooks {
id
name
}
}
When you modify the tags query to be type specific, the query returns the tags metadata for WorkbookA.
{
tags {
workbooks {
{ id: "A", name: "WorkbookA" }
{ id: "B", name: null }
}
}
Working with linked flow objects
Unlike upstreamFlows
and downstreamFlows
objects, which return all upstream and downstream flows, queries that include upstreamLinkedFlows
and downstreamLinkedFlows
objects return additional structural metadata about upstream and downstream flows. The upstreamLinkedFlows
and downstreamLinkedFlows
objects can provide information about order, distance, and relationship between flows that are directly upstream and downstream of one another.
For example, suppose you have a flow called Superstore. You can run the following query to compare the information returned for the flows upstream of the Superstore flow.
query upstreamflows_vs_upstreamlinkedflows {
flows(filter: {name:"Superstore_AllUp"}) {
name
id
upstreamFlows{
name
id
}
upstreamLinkedFlows{
asset{
name
id
}
toEdges
fromEdges
}
}
}
The above query returns the following information.
{
"data": {
"flows": [
{
"name": "Superstore_Customers",
"id": "089839c4-7edd-b887-3178-fcc2367e938b",
"upstreamFlows": [
{
"name": "Superstore_Pods",
"id": "66e8f90d-f02d-eea1-850e-2014b4b09b96"
},
{
"name": "Superstore_Marketing",
"id": "7efe5f86-511b-760b-18d4-1a6a28c220b5"
},
{
"name": "Superstore_Operations",
"id": "cd79250f-bc27-1d9d-7b22-aca1534863e1"
},
{
"name": "Superstore_Sales",
"id": "e78d4c54-df3a-12a9-ef1a-9849c2625b35"
}
],
"upstreamLinkedFlows": [
{
"asset": {
"name": "Superstore_Customers",
"id": "089839c4-7edd-b887-3178-fcc2367e938b"
},
"toEdges": [
"e78d4c54-df3a-12a9-ef1a-9849c2625b35",
"7efe5f86-511b-760b-18d4-1a6a28c220b5",
"cd79250f-bc27-1d9d-7b22-aca1534863e1"
],
"fromEdges": []
},
{
"asset": {
"name": "Superstore_Sales",
"id": "e78d4c54-df3a-12a9-ef1a-9849c2625b35"
},
"toEdges": [
"cd79250f-bc27-1d9d-7b22-aca1534863e1"
],
"fromEdges": [
"089839c4-7edd-b887-3178-fcc2367e938b"
]
},
{
"asset": {
"name": "Superstore_Marketing",
"id": "7efe5f86-511b-760b-18d4-1a6a28c220b5"
},
"toEdges": [],
"fromEdges": [
"089839c4-7edd-b887-3178-fcc2367e938b"
]
},
{
"asset": {
"name": "Superstore_Operations",
"id": "cd79250f-bc27-1d9d-7b22-aca1534863e1"
},
"toEdges": [
"66e8f90d-f02d-eea1-850e-2014b4b09b96"
],
"fromEdges": [
"089839c4-7edd-b887-3178-fcc2367e938b",
"e78d4c54-df3a-12a9-ef1a-9849c2625b35"
]
},
{
"asset": {
"name": "Superstore_Pods",
"id": "66e8f90d-f02d-eea1-850e-2014b4b09b96"
},
"toEdges": [],
"fromEdges": [
"cd79250f-bc27-1d9d-7b22-aca1534863e1"
]
}
]
}
]
},
}
From the upstreamFlows object, the following upstream flows are returned: Superstore_Pods, Superstore_Marketing, Superstore_Operations, and Superstore_Sales.
Whereas, from the upstreamLinkedFlows object, the following information is returned:
asset
parameter, you see Superstore_Customers is returned. This is the source flow or the flow from which you want to understand its relationship to other flows.fromEdges
parameter, you see three direct flows that Superstore_Customer links from: Superstore_Marketing, Superstore_Operations, and Superstore_Sales. In addition, you see additional flow relationships information about those three direct flows.
fromEdges
parameter shows Superstore_Customers as its direct upstream flow and the toEdges
parameter shows no direct downstream flows.toEdges
shows both Superstore_Customers and Superstore_Sales as its direct upstream flows and toEdges
shows Superstore_Pods directly downstream of it.toEdges
parameter, you see that Superstore_Customers has no direct flows it links to. In other words, Superstore_Customers is at the bottom of its relationship chain.