# Migrating Looker Views to Holistics > A practical guide on how to migrate your Looker views to Holistics models ## Overview A view in Looker corresponds to a model in Holistics. A view in Looker represents a database table or a derived table. In Holistics, this is equivalent to a [Table Model or Query Model](/reference/aml/model). Holistics Model has the equivalent common concepts like table name, dimension, and measure. ![Looker View to Holistics Model](https://cdn.holistics.io/product/modeling-looker-view-holistics-model-20250211-611.png) ## Step-by-Step Migration Tutorial ### Step 1: Identify View Type Determine if the view is based on a table or a derived query: - Table-based view → Table Model - Derived view → Query Model - Extended view → Extended Model :::note Looker has [2 types of derived views](https://cloud.google.com/looker/docs/derived-tables): - **SQL-based derived table version**: a derived view built from a SQL query - **Native derived table version**: a derived view built from an Explore Holistics only supports **SQL-based derived view** conversion. ::: ### Step 2: Create Model Structure #### For table-based views ```tsx title="views/orders.view.lkml" // Looker view: orders { sql_table_name: public.orders ;; # fields defined here... } ``` ```tsx title="models/orders.model.aml" // Holistics Model orders { //highlight-next-line type: 'table' //highlight-next-line table_name: 'public.orders' // fields defined here... } ``` For more details on table model, see [Table Model](/reference/aml/table-model). #### For SQL-based derived views ```tsx title="views/active_users.view.lkml" // Looker view: active_users { derived_table: { sql: SELECT user_id, COUNT(DISTINCT order_id) as order_count FROM orders WHERE status = 'completed' GROUP BY 1 ;; } } ``` ```tsx title="models/active_users.model.aml" // Holistics Model active_users { //highlight-next-line type: 'query' data_source_name: 'warehouse' query: @sql SELECT user_id, COUNT(DISTINCT order_id) as order_count FROM orders WHERE status = 'completed' GROUP BY 1;; } ``` For more details on query model, see [Query Model](/reference/aml/query-model). #### For extended views ```tsx title="views/extended_orders.view.lkml" // Looker view: extended_orders { extends: [orders] dimension: is_high_value { type: yesno sql: ${amount} > 1000 ;; } } ``` ```tsx title="models/extended_orders.model.aml" // Holistics Model extended_orders = orders.extend({ label: 'Extended Orders', dimension is_high_value { type: 'truefalse' definition: @sql {{ amount }} > 1000;; } }) ``` For more details on extended model, see [AML Extend](/reference/aml/extend). ### Step 3: Add Data Source Name to Your Models Unlike Looker where connections are defined at the model level, Holistics requires explicitly specifying the data source for each model. Check the `connection` property in your Looker model file and add it to your Holistics model: ```tsx title="Looker model file" connection: "warehouse" // Defined once at model level include: "views/*.view" explore: order_items { join: products { ... } join: orders { ... } } ``` ```tsx title="Holistics model file" Model order_items { data_source_name: 'warehouse' // Required in each model } ``` For more details on connection differences, see [Conceptual Differences: Data Source Connection](/docs/from-others/looker/conceptual-differences#data-source-connection). ### Step 4: Migrate Fields After setting up the model structure, migrate the fields following these dedicated guides: - For dimensions, follow the [migrating dimension guide](/docs/from-others/looker/dimension-migration) - For measures, follow the [migrating measure guide](/docs/from-others/looker/measure-migration) These guides provide detailed instructions for converting different types of fields and their properties. ### Step 5: Handle Persistence (for derived views) **In Looker**, persistence is configured within the derived table: ```tsx title="views/order_summary.view.lkml" view: order_summary { derived_table: { sql: SELECT user_id, COUNT(*) as order_count, SUM(amount) as total_amount FROM orders GROUP BY user_id ;; interval_trigger: "24 hours" } } ``` **In Holistics**, we handle this with Query Model persistence and schedules: Define the persistence in the model's definition, and set up the schedule in the `schedules.aml` file. ```tsx title="models/order_summary.model.aml" Model order_summary { type: 'query' query: @sql SELECT user_id, COUNT(*) as order_count, SUM(amount) as total_amount FROM orders GROUP BY user_id;; persistence: FullPersistence { schema: 'persisted' view_name: 'order_summary' } } ``` ```tsx title="schedules.aml" const schedules = [ // Refresh order_summary daily at midnight Schedule { models: [order_summary], cron: '0 0 * * *' // daily at midnight } ] ``` For more details on persistence options in Holistics, see our [Persistence documentation](/docs/persistence). ### Step 5: Test and Validate 1. Verify all fields are correctly migrated 2. Check data types are properly mapped 3. Test derived calculations 4. Compare query results with Looker ### Step 6: Continue migrating models and explores For more details on migrating models and explores, see the following guides: - [Model Migration Guide](/docs/from-others/looker/model-migration) - [Explore Migration Guide](/docs/from-others/looker/explore-migration) ## Detailed Feature Comparison | LookML Parameter | Purpose | Support | Holistics Equivalent & Implementation | |-----------------|---------|----------------------|-----------------------------------| | **Structural Parameters** | | | | | drill_fields | Control which fields to show when drilling/clicking a field | ❌ | Holistics currently supports drilling between dashboards as in [Drill Through](/docs/interactions/drill-through), but we haven't supported field-level control yet | | extend (for view) | Build a new View based on an existing View | ✅ | Holistics [AML Extend](/reference/aml/extend) | | extension | Force using `extends` on a view | 🧪 (partial) | Holistics doesn't support this exact concept but we can rebuild this via [Function](/reference/aml/func) | | include | Add files to a view | | | | test | Creates a data test to verify your model's logic. | ❌ | Holistics doesn't support this feature yet. | | set | Defines a set of dimensions and measures to be used in other parameters | ❌ | Holistics doesn't support this feature yet. | | view | Create a view | ✅ | Holistics [data model](/reference/aml/model) | | **Display Parameters** | | | | | label | The label of the view | ✅ | Holistics model's label `label: 'Your Model Label'` | | fields_hidden_by_default | When set to yes, hides all fields in the view by default. | 🧪 (partial) | Holistics doesn't support this exact concept but we can [extend](/reference/aml/extend#override-nested-properties) a Model to hide fields | | **Field Parameters** | | | | | suggestions (for view) | Enables or disables suggestions for all dimensions on this view | ❌ | | | **Query Parameters** | | | | | required_access_grants (for view) | Limits access to the view to only users whose user attribute values match the access grants | ❌ | | | sql_table_name (for view) | Changes the SQL table on which a view is based | ✅ | - `data_source_name`: for specifying the data source name- `table_name`: for specifying the table name in TableModel- For dynamic schema, see [our doc here](/docs/development/dynamic-schema)| | **Derived Table Parameters** | | | | | derived_table | A table based on a query | ✅ | [Query Model](/reference/aml/query-model) | | sql (for derived_table) | Declares the SQL query for a derived table | ✅ | Using `query: @sql your_query_here ;;` parameter in [Query Model](/reference/aml/query-model) | | explore_source | Defines a native derived table based on an [Explore](https://cloud.google.com/looker/docs/creating-ndts) | ❌ | Holistics doesn't support this feature yet. | | sql_create | Defines a SQL CREATE statement to create a PDT on a database dialect that requires custom DDL commands | ✅ | [Custom Persistence DDL](/docs/persistence#custom-persistence-ddl) | datagroup_trigger | Specifies the datagroup to use for the PDT rebuilding policy | ✔️ (partial) | Holistics doesn't have the exact concept of [datagroup](https://cloud.google.com/looker/docs/reference/param-model-datagroup), but we can set [schedule trigger](/docs/persistence#2-create-persistence-schedule) on individual query model | | interval_trigger | Specifies the interval to use for the PDT rebuilding policy | ✅ | Using Holistics schedule trigger defined in [`schedules.aml`](/docs/persistence#2-create-persistence-schedule) file | | sql_trigger_value | Specifies the condition that causes a PDT to be regenerated | ❌ | Not supported yet in Holistics. | | persist_for (for derived_table) | Sets the maximum age of a PDT before it is regenerated | ✔️ (partial) | Users cannot control this in Holistics yet, and the default value is [24 hours](/docs/persistence#when-will-the-persisted-table-be-invalidated) | | increment_key | The increment_key specifies the time increment for which fresh data should be queried and appended to the PDT. | ✅ | Using `increment_column: 'your_column'` parameter in [`persistence: IncrementalPersistence { }`](/docs/persistence#incremental-persistence) | | **Field Reference Parameters** | | | | | dimension | list of dimensions | ✅ | [Dimension migration guide](/docs/from-others/looker/dimension-migration) | | measure | list of measures | ✅ | [Measure migration guide](/docs/from-others/looker/measure-migration) | | dimension_group | Creates several time-based dimensions at the same time | ✅ | Holistics has several equivalent options: - [Date Drill](/docs/interactions/date-drills) - [Date Part](/docs/datetimes/date-parts) - [Time Intelligence Functions](/reference/aql/time-intelligence-functions) | | sets | Define a set of dimensions and measures to be used in other parameters | ✅ | Holistics doesn't have the exact set concept, but we a wide range of reusability features such as: - [Constant](/reference/aml/constant)- [Function](/reference/aml/func)- [Extend](/reference/aml/extend)- [String Interpolation](/reference/aml/string-interpolation) | | parameter, filter for Templated filters | Creates a filter-only field that can be used to filter Explores, Looks, and dashboards but that cannot be added to a result set. | ✅ | [Query Parameter](/docs/query-parameters) | (*) Looker Parameters that are not mentioned in this table are generally not supported