Saved Queries
Use queries to sync reusable SQL queries and link them to a synced database.
Saved queries are synced as team-shared. CI has no personal user context, so every query pushed by the CLI is visible to the whole team in UIGraph.
Requirements
- A
servicemust be defined. Configs without a service may only sync maps and frames. - Each query's
databasemust match anameunderdatabases. - Each query provides its SQL through exactly one of
queryText(inline) orpath(external file).
Minimal config
databases:
- name: ecommerce
dialect: mysql
dbType: MySQL
schemaPath: ./ecommerce-schema.sql
queries:
- name: orphaned-orders
database: ecommerce
queryText: "SELECT * FROM orders WHERE customer_id IS NULL"
tags: [data-quality]
Query fields
Each item requires:
name— stable key used to upsert the query on repeat syncsdatabase— must match adatabases[].name- exactly one of
queryTextorpath
Optional:
descriptiontags— list of strings
name is the upsert key
name is the stable identifier the gateway uses to upsert a query. Rename it and the next sync creates a new query instead of updating the existing one in place.
queryText vs path
Provide the SQL one of two ways — exactly one is required:
queryText— inline SQL stringpath— path to a.sqlfile, read as raw content at sync time
queries:
- name: top-customers-by-revenue
database: ecommerce
path: .uigraph/queries/top-customers-by-revenue.sql
description: Top 20 customers by lifetime revenue, last 90 days
tags: [reporting, revenue]
- name: daily-order-volume
database: ecommerce
queryText: "SELECT DATE(created_at) AS day, COUNT(*) AS orders FROM orders GROUP BY day ORDER BY day DESC"
description: Order count per day
tags: [reporting]
External query files
Use queryFiles to keep query definitions in separate files instead of inline in .uigraph.yaml. Each listed file contains its own queries: list.
Inline queries and external queryFiles may be used together — the entries are merged.
.uigraph.yaml:
queries:
- name: orphaned-orders
database: ecommerce
queryText: "SELECT * FROM orders WHERE customer_id IS NULL"
tags: [data-quality]
queryFiles:
- .uigraph/queries/reporting.yaml
.uigraph/queries/reporting.yaml:
queries:
- name: top-customers-by-revenue
database: ecommerce
path: .uigraph/queries/top-customers-by-revenue.sql
description: Top 20 customers by lifetime revenue, last 90 days
tags: [reporting, revenue]
- name: daily-order-volume
database: ecommerce
queryText: "SELECT DATE(created_at) AS day, COUNT(*) AS orders FROM orders GROUP BY day ORDER BY day DESC"
description: Order count per day
tags: [reporting]
All paths — including each query's path — are resolved relative to the working directory where the CLI runs, not relative to the file that references them.
What the CLI does
For each query (inline and from queryFiles), the CLI:
- validates that
databasematches a defined database - validates that exactly one of
pathorqueryTextis set - reads the SQL from
queryText, or frompathif a file is used - sends the query text, metadata, and commit hash to the gateway
Queries are synced after database schemas, so a database referenced by a query is already present when the query is upserted.
Recommended usage
- keep
.sqlfiles in version control and reference them withpathfor anything non-trivial - use short inline
queryTextonly for one-line checks - keep
namestable so repeat syncs update in place rather than creating duplicates - group related queries into a
queryFilesfile per domain (e.g.reporting.yaml,data-quality.yaml)