Migrating from Looker
A practical guide for LookML developers moving to Celiq โ concept mapping, CML equivalents, and a step-by-step migration workflow.
Who it's for: LookML developers, Looker admins, and data engineers who need to reproduce their Looker models in Celiq.
Shortcut: Celiq can auto-import a Looker instance โ see Import from Looker or dbt.
If you've built semantic models in Looker, you already understand the core concepts that Celiq implements โ views, Explores, dimensions, measures, and row-level security. This guide maps every Looker concept to its Celiq equivalent and walks through a complete migration.
Concept mapping
| Looker | Celiq | Notes |
|---|---|---|
| LookML View | Node | Maps to a table; defines dimensions and measures |
| LookML Explore | Domain | Join graph; defines valid query starting points |
| LookML | CML | YAML-based modelling language |
| Looker IDE | Forge | Semantic IDE with validation and Git integration |
| Explore (UI) | Discover | No-code query builder |
| Look / Saved Explore | Prism | Saved query with visualisation |
| Dashboard | Mosaic | Collection of tiles with auto-refresh |
| Space / Folder | Vault | Folder with access controls |
| user_attribute + access_filter | Data Key | Row-level security |
| Column-level security | Data Gate | Field-level security |
| Dev mode | Draft mode | Personal branch for model changes |
| Production mode | Live mode | Published semantic model |
| Luminary | Admin | Workspace administrator role |
| Weaver | Developer | Model developer and content creator |
| Tracer | Standard user | Analyst with Explore/Discover access |
| Lens | Viewer | Read-only access to shared content |
| Orion | (no equivalent) | AI analyst; natural language โ SQL |
LookML to CML translation
View โ Node
Looker (LookML):view: orders {
sql_table_name: public.orders ;;
dimension: order_id {
type: number
sql: ${TABLE}.id ;;
}
dimension_group: created {
type: time
timeframes: [date, week, month, year]
sql: ${TABLE}.created_at ;;
}
measure: total_revenue {
type: sum
sql: ${TABLE}.revenue ;;
value_format_name: usd
}
measure: order_count {
type: count
}
}node: orders
dataset: orders
dimensions:
- name: order_id
type: number
sql: id
- name: created_at
type: time
grains: [day, week, month, year]
sql: created_at
measures:
- name: total_revenue
type: sum
sql: revenue
format: currency
- name: order_count
type: countKey differences:
sql_table_nameis replaced bydataset:(referencing a logical dataset)${TABLE}.fieldbecomes justfield(or${TABLE}.fieldis also accepted)dimension_groupwithtimeframesbecomes a singletype: timedimension withgrains:type: countworks the same โ no SQL expression needed
Explore โ Domain
Looker (LookML):explore: orders {
label: "E-commerce Orders"
join: customers {
type: left_outer
sql_on: ${orders.customer_id} = ${customers.id} ;;
relationship: many_to_one
}
join: products {
type: left_outer
sql_on: ${orders.product_id} = ${products.id} ;;
relationship: many_to_one
}
}domain: ecommerce
label: E-commerce Orders
primary_node: orders
joins:
- node: customers
type: left
sql: "${orders.customer_id} = ${customers.id}"
relationship: many_to_one
- node: products
type: left
sql: "${orders.product_id} = ${products.id}"
relationship: many_to_oneaccess_filter (RLS) โ Data Key
Looker (LookML):explore: orders {
access_filter: {
field: orders.customer_region
user_attribute: region
}
}node: orders
data_keys:
- field: customer_region
user_attribute: regionData Keys apply at the node level, not the domain level. They filter every query against the node, regardless of which domain the query comes from.
always_filter โ default filters
Looker's always_filter applies a filter to all Explore queries. In Celiq, use Filter Mappings on a Reveal, or apply default filters in a Domain's default_filters block (see CML Reference).
Migration workflow
Step 0 โ Decide: auto-import vs. manual
Celiq's Import tool can connect to your Looker instance and auto-generate CML nodes and domains from your LookML. This is the fastest path for large models.
Use auto-import when:
- Your LookML is well-structured with clear view/Explore separation
- You have more than ~20 views to migrate
- Your LookML doesn't use heavy PDT (persistent derived tables) logic
Use manual migration when:
- Your LookML has complex PDTs you need to redesign as nodes with pre-computed datasets
- You want to use the migration as an opportunity to clean up and simplify the model
- You want full control over the resulting CML structure
Step 1 โ Inventory your Looker model
Before writing any CML:
- List every Explore that is actively used (check query counts in Looker's usage data)
- For each Explore, list the views it joins
- Note any
access_filter,sql_always_where, orrequired_access_grants - Identify PDTs โ these need special handling (see below)
Step 2 โ Map Explores to Domains
Each Looker Explore becomes one Celiq Domain. The Explore's base view becomes the Domain's primary_node.
If you have Explores that share the same base view but differ only in their joins, you have two options:
- Create one Domain with all possible joins and let Celiq prune unused ones at query time
- Create multiple Domains with different join sets (better for large models with performance concerns)
Step 3 โ Convert Views to Nodes
For each LookML view:
- Create the dataset (Lumen โ Physical Layer โ Datasets) or let Celiq auto-create it when you specify
dataset:in the node and validate - Write the CML node, translating:
dimension โ dimensions block
- measure โ measures block
- dimension_group โ single time dimension with grains:
- sql_table_name โ dataset: field name
Run Check & Save in Forge after each node to catch errors early.
Step 4 โ Handle PDTs
Looker PDTs (persistent derived tables) have no direct equivalent in Celiq. Your options:
Option A โ materialize in the warehouse: Run the PDT's SQL as a scheduled table refresh in your warehouse (dbt, Airflow, etc.). Create a dataset and node pointing to the materialized table. Option B โ use a domain with a derived node: For simpler PDTs (window functions, aggregations), define the logic as a node withsql: expressions. Celiq will compute it at query time.
Option C โ use CML derived nodes: Celiq supports sql: at the node level for derived columns. Write the derivation logic directly in the node's dimension/measure SQL.
Step 5 โ Migrate security rules
For each Looker access_filter, add the equivalent data_keys: block to the corresponding CML node.
For required_access_grants, use Data Gates โ field-level visibility controls based on user role.
Step 6 โ Rebuild Looks as Prisms
Saved Looks become Prisms in Celiq. For high-priority Looks:
- Open Discover and reproduce the query (select the same node/domain, dimensions, measures, filters)
- Choose a visualisation and configure it
- Save as a Prism
- Recreate the folder structure as Vaults
For bulk migration, the Celiq API (POST /api/reveals) can programmatically create Prisms from query specs.
Step 7 โ Rebuild Dashboards as Mosaics
Each Looker Dashboard becomes a Mosaic. Add tiles by selecting existing Prisms or creating inline Reveals.
Step 8 โ Validate with Evals
Once the model is built, create Evals โ prompt sets that test Orion's understanding of your domain. Good evals confirm that the semantic model correctly answers the questions your team actually asks.
Common pitfalls
| Looker pattern | Celiq equivalent | Watch out for |
|---|---|---|
${view_name.field} cross-view reference | ${node_name.field} | Node must be in the domain's join graph |
type: yesno dimension | type: boolean dimension | Syntax change only |
fanout_on | No direct equivalent | Design joins to avoid fan-out; Forge validation warns on fan-out risk |
required_joins | Not needed โ Celiq only joins nodes when fields from them are selected | Simpler mental model |
extends | Not yet supported | Duplicate the node and modify |
set: blocks | Not yet supported | Manage field visibility with Data Gates |
Related pages
- Import from Looker or dbt โ auto-import tool
- CML Reference โ complete field reference
- Platform Architecture โ how the layers fit together
- Semantic Layer Overview โ nodes, domains, metrics
- Data Keys โ row-level security
- Data Gates โ field-level security