You can run queries against the tables in your Lightdash project.
Tables are built from dbt models (either one, or many joined together).
Tables come from dbt models that have been defined in your dbt project’s schema.yml files.
If your dbt model has been defined in a .yml file, it will appear in Lightdash as a table.
For example, if we had this in our schema.yml files in dbt, we’d see a Table called users
in Lightdash.
You can read more about adding Tables to Lightdash here.
You can customize your Tables in your dbt model’s YAML file. Here’s an example of the properties used in defining a Table:
Here are all of the properties you can customize:
Property | Value | Note |
---|---|---|
label | string | Custom label. This is what you’ll see in Lightdash instead of the Table name. |
order_fields_by | ’index’ or ‘label’ | How the fields will be sorted in the sidebar. Read more about the order rules in here |
joins | array | Join logic to join other data models to the Table. Read more about joins in here. |
metrics | object | Model metrics. Read more about model metrics in here |
group_label | string | Group tables in the sidebar. Read more about the group label in here |
sql_filter | string | A permanent filter that will always be applied when querying this table directly. Read more about sql_filter below |
sql_where | string | Alias for sql_filter |
required_attributes | Object with { user_attribute, value } | Limits access to users with those attributes. Read more about user attributes in here |
group_details | Object with { label, description } | Describes the groups for dimensions and metrics |
default_filters | Array of { filter field value } | Dimension filters that will be applied when no other filter on those dimension exists. Read more about default_filters below |
dbt run
+ dbt refresh
before it will appear in LightdashLightdash gets information about your data models from dbt. But it gets information about the data generated by those data models from your data warehouse.
This means that if you add a new dbt model to your project or update a model so that you’re making changes to the table it generates, then you need to do two things before your changes will appear in Lightdash:
Materialize the new table/changes to the table (using dbt run).
You basically want the data in your data warehouse to be the new table you’re expecting. So you need to do dbt run
to update the table from the data model you just changed.Click dbt refresh in Lightdash.
This will re-sync your dbt project in Lightdash so that any changes you made to your dbt models is shown in Lightdash (e.g. adding a new table).By default, the fields in your sidebar for any table will appear alphabetically (order_fields_by: "label"
). Sometimes, you might not want your fields to appear alphabetically, but instead, in the same order as they are in your model’s dbt .yml file. You can achieve this by setting the order_fields_by
parameter in your table’s meta tag to index
, like this:
So, in the example above, the fields in the sidebar for “My Table” would appear in the order:
Instead of being listed alphabetically.
Here are some other things worth mentioning about the order_fields_by
parameter:
order_fields_by
is set to label
, which means that your fields will appear in the table listed alphabetically.meta
tag, under a dimension’s meta
), we force the following order on metrics if you set order_fields_by
to index
:
meta
meta
If you set this property, the table will be grouped in the sidebar with other tables with the same group label.
The tables in your sidebar will appear in the following order:
sql_filter
adds a filter to the table that cannot be removed in Lightdash. It is automatically added to the compiled SQL when running queries.
For example:
Any queries that I run using the Sales
table in Lightdash will always have a filter for sales_region = 'EMEA'
in their compiled SQL
Using sql_filter
with user attributes allows you to set up row-level security in your tables. You can reference user attributes in your sql_filter
using ${lightdash.attributes.my_attribute_name}
For example:
sql_filter
will only be applied when querying tables directly.For example:
sql_filter
applied to itsql_filter
from Table B will not be applied to the query (you would need to add this as a sql_filter
to Table A directly for it to apply)sql_filter
, the referenced table will always be joined in your queries.For example:
sql_filter: ${TABLE}.sales_region = 'EMEA' OR ${table_b}.sales_region IS NULL
Lightdash can use user attributes to limit some tables to some users.
In the example below, only users with is_admin
attribute true
can use the payments
table. Users without access to this table will not see it on the tables page
or the explore page
when joined to other tables.
If a user without access to this table runs a query that contains this table, they will get a Forbidden
error.
Use default_filters
to define filters on Dimensions that will be applied when no other user-defined filter on those Dimensions exists. Default filters will show apply to tables on load and can be populated with a pre-determined value. User them to suggest to users the kind of filters they might want to consider, or provide a default filtered view of a table that can be changed if needed.
An optional required
flag can be added - in which case the filter cannot be removed. This can be particulalry useful if you have a large table and want to force users to filter on a partitioned date.
Below you can see there is a default filter with the optional required flag, that will have show the last 14 days of data by default.
A required filter’s field reference can’t be changed, but its operator (is, is not, etc.) and value can be changed when querying the table from the UI
AND
In the example above, the orders
table will have a default filter of date
in the past 14 days and status
completed. Both can be removed by the user, as the required
flag is not present.
Note that we do also support a legacy structure for defining required filters, see below:
You can specify a primary key for your model to uniquely identify each row. This is important for tables as it helps Lightdash understand the relationships between tables and prevent data duplication, especially when dealing with SQL fanouts in joins.
The primary key can be defined in two ways:
If your table has a single column that uniquely identifies each row, you can define it as a string:
If your table requires multiple columns to uniquely identify each row, you can define the primary key as an array of strings:
Using a properly defined primary key helps Lightdash optimize queries and provide accurate results when working with joined tables. It’s especially important for preventing metric inflation in SQL joins where duplicate rows can lead to incorrect aggregations.
Type | Example (in English) | Example (as code) |
---|---|---|
is | User name is equal to katie | user_name: “katie” |
is not | User name is not equal to katie | user_name: “!katie” |
contains | User name contains katie | user_name: “%katie%“ |
does not contain | User name does not contain katie | user_name: ”!%katie%“ |
starts with | User name starts with katie | user_name: “katie%“ |
ends with | User name ends with katie | user_name: “%katie” |
is greater than (number) | Number of orders is greater than 4 | num_orders: ”> 4” |
in the past (date) (interval) | Date is before x (days / months / years) | date: “inThePast 14 months” |
in the next (date) (interval) | Date is after x (days / months / years) | date: “inTheNext 14 days” |
is greater than or equal to | Number of orders is greater than or equal to 4 | num_orders: ”>= 4” |
is less than | Number of orders is less than 4 | num_orders: ”< 4” |
is less than or equal to | Number of orders is less than or equal to 4 | num_orders: ”<= 4” |
is null | Status is NULL | status: “null” |
is not null | Status is not NULL | status: “!null” |
is [boolean] | Is complete is true | is_complete: “true” |
is not [boolean] | Is complete is false or null | is_complete: “!true” |
You can run queries against the tables in your Lightdash project.
Tables are built from dbt models (either one, or many joined together).
Tables come from dbt models that have been defined in your dbt project’s schema.yml files.
If your dbt model has been defined in a .yml file, it will appear in Lightdash as a table.
For example, if we had this in our schema.yml files in dbt, we’d see a Table called users
in Lightdash.
You can read more about adding Tables to Lightdash here.
You can customize your Tables in your dbt model’s YAML file. Here’s an example of the properties used in defining a Table:
Here are all of the properties you can customize:
Property | Value | Note |
---|---|---|
label | string | Custom label. This is what you’ll see in Lightdash instead of the Table name. |
order_fields_by | ’index’ or ‘label’ | How the fields will be sorted in the sidebar. Read more about the order rules in here |
joins | array | Join logic to join other data models to the Table. Read more about joins in here. |
metrics | object | Model metrics. Read more about model metrics in here |
group_label | string | Group tables in the sidebar. Read more about the group label in here |
sql_filter | string | A permanent filter that will always be applied when querying this table directly. Read more about sql_filter below |
sql_where | string | Alias for sql_filter |
required_attributes | Object with { user_attribute, value } | Limits access to users with those attributes. Read more about user attributes in here |
group_details | Object with { label, description } | Describes the groups for dimensions and metrics |
default_filters | Array of { filter field value } | Dimension filters that will be applied when no other filter on those dimension exists. Read more about default_filters below |
dbt run
+ dbt refresh
before it will appear in LightdashLightdash gets information about your data models from dbt. But it gets information about the data generated by those data models from your data warehouse.
This means that if you add a new dbt model to your project or update a model so that you’re making changes to the table it generates, then you need to do two things before your changes will appear in Lightdash:
Materialize the new table/changes to the table (using dbt run).
You basically want the data in your data warehouse to be the new table you’re expecting. So you need to do dbt run
to update the table from the data model you just changed.Click dbt refresh in Lightdash.
This will re-sync your dbt project in Lightdash so that any changes you made to your dbt models is shown in Lightdash (e.g. adding a new table).By default, the fields in your sidebar for any table will appear alphabetically (order_fields_by: "label"
). Sometimes, you might not want your fields to appear alphabetically, but instead, in the same order as they are in your model’s dbt .yml file. You can achieve this by setting the order_fields_by
parameter in your table’s meta tag to index
, like this:
So, in the example above, the fields in the sidebar for “My Table” would appear in the order:
Instead of being listed alphabetically.
Here are some other things worth mentioning about the order_fields_by
parameter:
order_fields_by
is set to label
, which means that your fields will appear in the table listed alphabetically.meta
tag, under a dimension’s meta
), we force the following order on metrics if you set order_fields_by
to index
:
meta
meta
If you set this property, the table will be grouped in the sidebar with other tables with the same group label.
The tables in your sidebar will appear in the following order:
sql_filter
adds a filter to the table that cannot be removed in Lightdash. It is automatically added to the compiled SQL when running queries.
For example:
Any queries that I run using the Sales
table in Lightdash will always have a filter for sales_region = 'EMEA'
in their compiled SQL
Using sql_filter
with user attributes allows you to set up row-level security in your tables. You can reference user attributes in your sql_filter
using ${lightdash.attributes.my_attribute_name}
For example:
sql_filter
will only be applied when querying tables directly.For example:
sql_filter
applied to itsql_filter
from Table B will not be applied to the query (you would need to add this as a sql_filter
to Table A directly for it to apply)sql_filter
, the referenced table will always be joined in your queries.For example:
sql_filter: ${TABLE}.sales_region = 'EMEA' OR ${table_b}.sales_region IS NULL
Lightdash can use user attributes to limit some tables to some users.
In the example below, only users with is_admin
attribute true
can use the payments
table. Users without access to this table will not see it on the tables page
or the explore page
when joined to other tables.
If a user without access to this table runs a query that contains this table, they will get a Forbidden
error.
Use default_filters
to define filters on Dimensions that will be applied when no other user-defined filter on those Dimensions exists. Default filters will show apply to tables on load and can be populated with a pre-determined value. User them to suggest to users the kind of filters they might want to consider, or provide a default filtered view of a table that can be changed if needed.
An optional required
flag can be added - in which case the filter cannot be removed. This can be particulalry useful if you have a large table and want to force users to filter on a partitioned date.
Below you can see there is a default filter with the optional required flag, that will have show the last 14 days of data by default.
A required filter’s field reference can’t be changed, but its operator (is, is not, etc.) and value can be changed when querying the table from the UI
AND
In the example above, the orders
table will have a default filter of date
in the past 14 days and status
completed. Both can be removed by the user, as the required
flag is not present.
Note that we do also support a legacy structure for defining required filters, see below:
You can specify a primary key for your model to uniquely identify each row. This is important for tables as it helps Lightdash understand the relationships between tables and prevent data duplication, especially when dealing with SQL fanouts in joins.
The primary key can be defined in two ways:
If your table has a single column that uniquely identifies each row, you can define it as a string:
If your table requires multiple columns to uniquely identify each row, you can define the primary key as an array of strings:
Using a properly defined primary key helps Lightdash optimize queries and provide accurate results when working with joined tables. It’s especially important for preventing metric inflation in SQL joins where duplicate rows can lead to incorrect aggregations.
Type | Example (in English) | Example (as code) |
---|---|---|
is | User name is equal to katie | user_name: “katie” |
is not | User name is not equal to katie | user_name: “!katie” |
contains | User name contains katie | user_name: “%katie%“ |
does not contain | User name does not contain katie | user_name: ”!%katie%“ |
starts with | User name starts with katie | user_name: “katie%“ |
ends with | User name ends with katie | user_name: “%katie” |
is greater than (number) | Number of orders is greater than 4 | num_orders: ”> 4” |
in the past (date) (interval) | Date is before x (days / months / years) | date: “inThePast 14 months” |
in the next (date) (interval) | Date is after x (days / months / years) | date: “inTheNext 14 days” |
is greater than or equal to | Number of orders is greater than or equal to 4 | num_orders: ”>= 4” |
is less than | Number of orders is less than 4 | num_orders: ”< 4” |
is less than or equal to | Number of orders is less than or equal to 4 | num_orders: ”<= 4” |
is null | Status is NULL | status: “null” |
is not null | Status is not NULL | status: “!null” |
is [boolean] | Is complete is true | is_complete: “true” |
is not [boolean] | Is complete is false or null | is_complete: “!true” |