4 real examples

Best practice

Catching missing tables and stale references before a dashboard breaks

Why does a model look fine until someone runs it?

The rule

Trust: Inferred

Check every reference before anyone runs it: each table, field and explore that a model or dashboard names must exist. A model can read fine and still point at tables that are not there. Nothing fails until someone opens the chart, often long after the change that broke it.

Why it matters

Trust: Inferred

A LookML file can reference views, fields and explores that no file declares. Nothing fails until someone runs the query, and a reader of the repo cannot tell what those references meant.

Missing views remove the evidence needed to check grain and keys. Stale field names fail at query time for whoever clicks the tile, often long after the change that broke them.

How to check your own model

Trust: Suggested
  1. List every table, view and explore the model names, including derived tables it reads by name, and confirm each one exists.
  2. Validate dashboards against every model that includes them.
  3. Keep file names aligned with the names they declare, or note the mapping at the top of the file.
  4. Run the check in your build (Looker's validator, dbt parse, a query against the catalog) so a broken reference stops the release.

A safer shape

Check raw tables in the catalog, model objects in the model

Trust: Suggested

Two kinds of reference break differently. Raw tables the model reads directly can be checked against the warehouse catalog before each release. Views and derived tables defined in the model itself are checked by the model's own validator; a missing LookML view is not a missing table.

Show the suggested SQL: raw tables the model reads
Suggested, not from source
WITH expected AS (  SELECT 'users' AS table_name UNION ALL  SELECT 'user_transactions' UNION ALL  SELECT 'subscriptions' UNION ALL  SELECT 'messages' UNION ALL  SELECT 'propositions')SELECT e.table_nameFROM expected AS eLEFT JOIN information_schema.tables AS t  ON t.table_name = e.table_name AND t.table_schema = current_schema()WHERE t.table_name IS NULL

Where it shows up in real projects 4

sessions: Built on four views that are not here

Trust: Source-defined

The sessions derived table reads sessions_basic, sessions_geo, sessions_last_page and sessions_technology by SQL_TABLE_NAME. None is declared in the repo.

Source: user_sessions.view.lookml L69-89
dating_platform/user_sessions.view.lookmlL69-89
        t.dvce_ismobile,        t.dvce_screenwidth,        t.dvce_screenheight      FROM ${sessions_basic.SQL_TABLE_NAME} AS s      LEFT JOIN ${sessions_geo.SQL_TABLE_NAME} AS g        ON s.app_id = g.app_id AND        s.domain_userid = g.domain_userid AND        s.domain_sessionidx = g.domain_sessionidx      LEFT JOIN ${TABLE}.sessions_landing_page AS l        ON s.app_id = l.app_id AND        s.domain_userid = l.domain_userid AND        s.domain_sessionidx = l.domain_sessionidx      LEFT JOIN ${sessions_last_page.SQL_TABLE_NAME} AS l2        ON s.app_id = l2.app_id AND        s.domain_userid = l2.domain_userid AND        s.domain_sessionidx = l2.domain_sessionidx      LEFT JOIN ${TABLE}.sessions_source AS s2        ON s.app_id = s2.app_id AND        s.domain_userid = s2.domain_userid AND        s.domain_sessionidx = s2.domain_sessionidx      LEFT JOIN ${sessions_technology.SQL_TABLE_NAME} AS t        ON s.app_id = t.app_id AND        s.domain_userid = t.domain_userid AND        s.domain_sessionidx = t.domain_sessionidx    sql_trigger_value: SELECT COUNT(*) FROM ${TABLE}.events_atomic    distkey: domain_userid    sortkeys:

dating-platform, user_sessions.view.lookml, lines 69-89

enterprise: Explores based on missing views

Trust: Source-defined

The tests explore is based on user_metrics, and several joins target users. Neither view exists in the repo.

Source: enterprise.model.lookml L55-61
dating_platform/enterprise.model.lookmlL55-61
  joins:  - join: propositions    sql_on: propositions.proposition_template_id = date_ideas.id- explore: tests  view: user_metrics  label: Test Metrics  joins:  - join: user_experiment_buckets    sql_on: user_metrics.id = user_experiment_buckets.user_id    fields: []  - join: tests    from: experiments    sql_foreign_key: user_experiment_buckets.experiment_id

dating-platform, enterprise.model.lookml, lines 55-61

business dashboards: Tiles on explores no model declares

Trust: Source-defined

Business overview tiles query a users explore. No model in the repo declares one, so these tiles cannot run as written.

Source: company_overview.dashboard.lookml L62-73
dating_platform/company_overview.dashboard.lookmlL62-73
    y_axis_min: null    y_axis_max: null    hide_points: true  - name: users_map    title: Where are Users?    type: looker_geo_coordinates    explore: users    map: usa    dimensions:    - users.zipcode    measures:    - users.count    limit: null    width: null    height: null  - name: users_by_orientation    title: Users by Orientation    type: looker_pie

dating-platform, company_overview.dashboard.lookml, lines 62-73

visitors: Drill sets that point nowhere

Trust: Source-defined

individual_detail lists referer_host and number_of_events, which the view does not declare. A drill on visitor count fails or shows fewer columns than intended.

Source: guests.view.lookml L239-255
dating_platform/guests.view.lookmlL239-255
    - referer_medium_count    - referer_source_count    - referer_term_count    individual_detail:    - user_id    - first_touch    - last_touch    - referer_medium    - referer_source    - referer_host    - referer_url_host    - referer_url_path    - campaign_medium    - campaign_source    - campaign_name    - landing_page_url    - number_of_sessions    - number_of_events    - session_stream    - event_stream

dating-platform, guests.view.lookml, lines 239-255

Other places it occurs