This is an advanced topic that assumes that the reader has a solid knowledge of LookML.
Overview
As your LookML model expands in size and complexity, it becomes increasingly useful to reuse your LookML in multiple places. The extends
parameter allows you to reuse code, which helps you to do the following:
- Write DRY (don’t repeat yourself) code, so that you can define things in just one place, making your code more consistent and faster to edit
- Manage different field sets for different users
- Share design patterns in different parts of your project
- Reuse sets of joins, dimensions, or measures across a project
To extend a LookML object, you create a new LookML object and then add the extends
parameter to indicate that the new object is an extension of an existing object. This means that your project will have two versions of the LookML object. If there are any conflicts, the extending object will take precedence and override the settings of the object being extended. See the Implementation Details for extends
section below for details.
Check out LookML refinements.
Extending a view or an Explore is ideal for scenarios where you want to have multiple versions of the view or Explore. But if your goal is simply to modify a view or an Explore without editing the LookML file that contains it, you may want to use a refinement instead.
You can also use anextends
parameter inside a refinement.
See the LookML Refinements documentation page for more information and use cases.
You can extend views, Explores, and LookML dashboards:
Models cannot be extended, and you cannot include a model file in another model file. Instead, if you want to reuse or extend Explores across models, you can create a separate Explore file, then include that Explore file in a model file. You can find a detailed example in the Help Center article on Extending Explores to a Different Model.
See below for examples of extending an Explore and extending a LookML dashboard.
Extending an Explore
Here is an example of extending an Explore:
In this example we have an Explore called Customer, and we created a second Explore called Transaction that extends it. Everything that is in Customer, such as its joins, will be included in Transaction. Anything that is in Transaction will remain in Transaction.
But notice there is a conflict: The Customer Explore says the persist_for
setting should be 12 hours, but the Transaction Explore says it should be 5 minutes. For the Transaction Explore, the persist_for: "5 minutes"
setting will be used, because it overwrites the setting from the Explore it’s extending.
Extending a LookML dashboard
To extend a LookML dashboard, both the extended and extending dashboards must be included in the model file. If a dashboard using the extends
parameter is included in a model file without the base dashboard it extends, you’ll get a LookML validation error that the base dashboard can’t be found (among other errors).
Here’s an example dashboard file:
File: faa.dashboard.lookml
We can create a new LookML dashboard file and extend the FAA dashboard by adding a new tile:
File: faa_additional.dashboard.lookml
Because it extends the FAA dashboard, the FAA Additional dashboard will include any tiles that are defined in the faa.dashboard.lookml
file. In addition, the FAA Additional dashboard will have any tiles that are defined in its own faa_additional.dashboard.lookml
file.
The easiest way to create a LookML dashboard is to get the LookML from a user-defined dashboard. You can also use this technique to get the LookML for individual dashboard tiles. If you are using this method, be very sure that the positions of your tiles don’t overlap. In the example above, the tiles are both on the top row of the dashboard, which is indicated by row: 0
:
File: faa.dashboard.lookml
However, the new tile we’re adding in the FAA Additional dashboard is in col: 8
so it’s displayed next to the tile from the extended dashboard:
File: faa_additional.dashboard.lookml
This is an easy thing to miss, since these elements are in different dashboard files. So if you’re adding tiles to an extended dashboard, be sure to check for positioning conflicts between tiles in the extended dashboard and tiles in the extending dashboard.
Requiring extension
You can use the extension: required
parameter to flag a LookML object as requiring extension, which means that the object cannot be used on its own. An object with extension: required
is not visible to users on its own; it is intended only to act as a starting point to be extended by another LookML object. The extension
parameter is supported for Explores, views, and LookML dashboards.
An explore
with extension: required
cannot be used as an explore_source
for a data test. The LookML Validator will generate an error stating that the explore_source
cannot be found.
Using metadata to see extensions for an object
If your Looker admin has enabled the IDE Metadata Sidebar Labs feature, you can click on an explore
or a view
parameter in the Looker IDE and use the metadata panel to see any extensions on the object, or to see what object it extends. See the Metadata for LookML objects documentation page for information.
Implementation details for extends
These are the steps that Looker takes when extending a LookML object:
- Copy the object being extended: Looker makes a copy of the LookML for the view, Explore, or LookML dashboard that is being extended. This new copy is the extending object.
- Merge the LookML of the two copies: Looker merges the LookML of the extended object into the extending object.
- Resolve conflicts between the copies: If a LookML element is defined in both the extended object and the extending object, the version in the extending object is used.
- Apply the LookML: Once all conflicts are resolved, Looker interprets the resultant LookML using the standard logic. In other words, Looker will use all the standard defaults and assumptions as with with any other view, Explore, or LookML dashboard.
The following sections show the specifics of these steps, extending a view as an example. Here is the LookML for our base view, the User view:
Here is the LookML for the User With Age Extensions view, which extends the User view:
Step 1: Copy the LookML
In this case the users
view is being extended into the users_with_age_extensions
view. Since users
is the view that is being extended, a copy of it is made before merging. Understanding that a copy is made is not particularly important, other than to realize that the original users
view is left unchanged, and usable as normal.
Step 2: Merge the copies
The next step is for all of the LookML from the extended view (users
) to be merged into the extending view (users_with_age_extensions
). It’s important to understand the nature of this merge, which is simply a merging of LookML objects. In practical terms this means that any explicitly written LookML gets merged, but the default LookML values that you haven’t written down don’t get merged. In a sense, it’s really just the text of the LookML that is getting put together, and none of the meaning of that text.
Step 3: Resolve conflicts
The third step is resolving any conflicts between the merged views. The extending view is the view that will “win,” which in this case is users_with_age_extensions
:
- The extending view name (
users_with_age_extensions
) overrides the extended view name (users
). - The extending value for
suggestions: no
overrides the extended valuesuggestions: yes
. - The extending view has a dimension called
age
, which doesn’t exist in the extended view (no conflict). - The extended view has a dimension called
name
, which doesn’t exist in the extending view (no conflict). - The
status
dimension’stype: string
value in the extending view overrides thetype: number
value in the extended view. - The
status
dimension has asql
parameter, which doesn’t exist in the extending view (no conflict).
The fact that default LookML values aren’t being considered yet is important, because you don’t want to make the mistake of thinking that conflicts between default values are getting resolved. In actuality, they’re just being ignored at this step. That is why we need to explicitly add additional parameters when extending objects:
- When extending a view, we add the
sql_table_name
andinclude
parameters. - When extending an Explore, we add the
view_name
andview_label
parameters.
In this particular example we have not added sql_table_name
to the User view, which is going to cause some problems in the next step.
Step 4: Interpret the LookML as normal
In the final step, the resulting LookML is interpreted as normal, including all the default values. In this particular example we’ve ended up with LookML that includes view: users_with_age_extensions
, but no sql_table_name
parameter. As a result, Looker is going to assume that the value of sql_table_name
is equal to the view name:
The problem is that there is probably no table in our database called users_with_age_extensions
. This is why we need to add a sql_table_name
parameter to any view that is going to be extended. Adding view_name
and view_label
to Explores that will be extended avoids similar problems.
Example use cases
The following sections give some examples of how you can use extends in your project. For advanced use cases and troubleshooting tips, see the Advanced Extends Use Case Troubleshooting Help Center article.
Extending more than one object at the same time
It is possible to extend more than one dashboard, view, or Explore at the same time. For example:
The extension process works exactly as described above, but you’ll need to keep one extra rule in mind about how conflicts are resolved. If there are any conflicts between the multiple items listed in the extends
parameter, priority is given to the items listed last. So in the example above, if there were conflicts between user_info
and marketing_info
, the marketing_info
Explore would win.
Chaining together multiple extends
You can also chain together as many extends as you’d like. For example:
Again, the extension process works exactly as described above, with one extra rule about conflict resolution. If there are any conflicts, priority is given to the last item in the chain of extends. In this example:
orders
would have priority over bothuser_info
andmarketing_info
user_info
would have priority overmarketing_info
Additional options with lists
When working with lists you may choose to combine them, instead of having the extending object’s list be the winner. Consider this simple extension with a conflicting list called animals
:
In this case the pets
view is doing the extending, and will therefore win, making animals
contain [dog, cat]
. However, by making use of the special EXTENDED*
set, you can combine the lists instead:
Now the animals
list will contain [dog, cat, goldfish, guppy]
.
Combining instead of replacing during conflict resolution
In the basic behavior described above we mentioned that, if there are any conflicts during extension, the extending object wins. For example, take this simple extension:
You can see there is a conflict of the sql
parameter within the description
dimension. Typically, the definition from product_short_descriptions
will simply overwrite the definition from products
because it is doing the extending.
However, you can also choose to combine the definitions if you like. To do so, you’ll use the ${EXTENDED}
keyword like this:
Now the conflict of the sql
parameter will be addressed differently. Instead of the product_short_descriptions
definition winning, it will take the definition from products
and insert it where ${EXTENDED}
is used. The resulting definition for description
in this case will be: LEFT(${TABLE}.full_description, 50)
.
Things to consider
When extending an object, be aware that localization rules apply to your extensions as well. If you are extending an object and then defining new labels or descriptions, you should provide localization definitions in your project’s locale strings files. See the Localizing Your LookML Model documentation page for more information.