SuperAPI AI Directory

generate-view-from-table

Data & analytics

View repository

Updated 10-21 04:05

About this skill

Generate Bronze View from Table (generate-view-from-table)

Overview and goal

In the Medallion LookML architecture (agentic-lookml), every physical database table is represented by a 1:1 autogenerated view in bronze/:table.view.lkml. Agents must never hand-write or hand-edit bronze/:table.view.lkml files. Run this skill for all physical tables referenced in the SQL queries every time (and whenever lkr parse sql-lookml-compare reveals a missing Bronze view or unmodeled_db_columns) so bronze/:table.view.lkml is always generated or refreshed directly from the database schema before authoring any refinements, Silver *_fields views, NDTs, or Explores.

Detecting missing or stale Bronze views with sql-lookml-compare

Run lkr parse sql-lookml-compare against the SQL query and local LookML project directory:

uv run lkr parse sql-lookml-compare \
  --sql "SELECT o.order_id, o.user_id, o.total_amount FROM analytics.ecomm.orders AS o" \
  --path ./lookml_project

Inspect each QueryLookmlMapping entry in queries[] by comparing parsed_query.tables against views:

  1. Identify all physical tables in parsed_query.tables. Each entry is a TableRef with name (table name), db (schema or dataset name), catalog (database or GCP project ID), and alias. Exclude any entry whose name matches a CTE defined in parsed_query.ctes[].name.
  2. Check for a missing Bronze view. If a physical table in parsed_query.tables has no matching entry in views (where views[].sql_table matches the table), no LookML view exists for that table yet. Trigger Bronze view generation immediately before attempting any downstream modeling.
  3. Check for unmodeled physical columns on an existing Bronze view. If the physical table matches an existing bronze/:table.view.lkml in views, inspect views[].unmodeled_db_columns. When unmodeled_db_columns is non-empty, the SQL query references physical columns on that table that are missing from bronze/:table.view.lkml. Regenerate the Bronze view from the database table rather than hand-editing bronze/:table.view.lkml.

Collision-aware Bronze folder routing

Before running the generator, determine the target folder inside bronze/ based on table-name uniqueness across the project:

Scenario Target folder (--folder / folder_name) Resulting file path
No table name collision in bronze/ (default) bronze bronze/:table.view.lkml
Table name :table collides across different schemas (db) bronze/:schema bronze/:schema/:table.view.lkml
:schema.:table also collides across different databases or GCP projects (catalog) bronze/:dataset_or_database/:schema bronze/:dataset_or_database/:schema/:table.view.lkml

If generating a new table causes a collision with an existing flat bronze/:table.view.lkml from another schema, move the existing view (and its companion .refinement.lkml if one exists) into its bronze/:schema/ subfolder and update its include: references so both tables follow the collision hierarchy cleanly.

Generating the Bronze view

Choose one of the three generation methods below depending on the active environment.

Using lkr tools lookml create CLI (recommended)

The lkr tools lookml create command switches to the Looker dev workspace, resets to production, creates a sync branch, invokes generate_lookml_with_new_files with file_type_for_explores="none", generate_descriptions=True, and add_autogenerated_header=True (# AUTOGENERATED), and commits/deploys the generated .view.lkml file:

# Generate a single Bronze view from a database table
uvx lkr-dev-cli tools lookml create \
  --project-id "<project_id>" \
  --connection "<connection_name>" \
  --schema "<schema_name>" \
  --table "<table_name>" \
  --folder "bronze"

# Pull the newly generated Bronze view into the local LookML workspace
uvx lkr-dev-cli tools lookml pull ./lookml_project --project-id "<project_id>"

If multiple tables in a schema are missing from bronze/, pass --match "<schema_name>.*" or run lkr tools lookml create for each missing table identified in parsed_query.tables. Note that lkr tools lookml create refuses to overwrite an existing .view.lkml file that lacks the # AUTOGENERATED header unless --allow-update-without-header is passed.

Using lkr code-mode sandbox --dev-mode (generate_lookml_with_new_files)

When operating inside an active branch or lkr code-mode sandbox session, run scripts/generate_bronze_view.py with --dev-mode so Looker generates only the 1:1 physical .view.lkml files in bronze/ without resetting the active branch or creating raw explores:

lkr --base-url="$BASE_URL" --dev code-mode sandbox --dev-mode \
  --file=.agents/skills/generate-view-from-table/scripts/generate_bronze_view.py \
  --var project_id="<project_id>" \
  --var model_name="<model_name>" \
  --var connection_name="<connection_name>" \
  --var schema_name="<schema_name>" \
  --var table_name="<table_a>,<table_b>" \
  --var folder_name="bronze"

After sandbox generation finishes, pull the generated files locally with lkr --base-url="$BASE_URL" --dev tools lookml pull ./lookml_project --project-id "<project_id>".

Using the Looker MCP Server (generate_view_from_table / create_view_from_table)

When connected to a Looker instance via the Looker MCP Server (without direct CLI write access to the remote project):

  1. Call the dev_mode MCP tool with true so file generation runs in the developer workspace.
  2. Call generate_view_from_table (or create_view_from_table on MCP Toolbox servers) with the target project_id, connection, schema (parsed_query.tables[].db), table (parsed_query.tables[].name), and target folder bronze (or bronze/<schema>).
  3. Fetch the generated view content with get_project_file (or pull via lkr tools lookml pull) so the local bronze/:table.view.lkml file matches the instance.

Post-generation verification and refinement boundary

After generating and pulling bronze/:table.view.lkml, complete two verification steps before continuing with agentic-lookml:

  1. Re-run lkr parse sql-lookml-compare against the SQL query and local LookML directory. Confirm that every physical table in parsed_query.tables now resolves to a LookmlViewMatch entry in views pointing to bronze/:table.view.lkml and that unmodeled_db_columns is empty ([]).
  2. Respect the Bronze refinement boundary. Leave bronze/:table.view.lkml untouched (it already contains the autogenerated physical dimensions, basic dimension_group blocks, and measure: count). If the SQL query requires a primary key override (primary_key: yes), a composite primary key (dimension: pk), calculated dimensions, type: duration dimension groups, hidden: yes and suggestable: no flags on raw JSON columns, partition/clustering metadata descriptions, or single-table measures (sum, average, count_distinct, filtered single-table measures, or single-table ratios), create bronze/:table.refinement.lkml on-demand with include: ":table.view.lkml" as its first line.