Migrate from Snowflake Semantic Views
Convert your Snowflake semantic views into governed Malloy semantic models
Snowflake semantic views and Malloy are close cousins — both are dimension, measure, and relationship graphs over SQL tables. That makes this one of the cleanest migrations: Credible reads your semantic view definition, maps it almost concept-for-concept to Malloy, and — where you connect it — validates against Snowflake's own verified queries.
What Credible Reads
Your native SEMANTIC VIEW objects — logical tables, relationships, facts, dimensions, and metrics — or any legacy Cortex Analyst YAML models. The agent works from the exported definition (the CREATE SEMANTIC VIEW DDL or the YAML). Connecting to Snowflake — via SQL (DESCRIBE SEMANTIC VIEW, SHOW SEMANTIC VIEWS) or the Snowflake-managed MCP server (Cortex) — is optional: it lets the agent read views in place and run parity queries under Snowflake's own RBAC.
What Comes Across
The everyday modeling carries over. Here's how the bigger pieces land — and where they get better:
| In Snowflake | In Credible |
|---|---|
| Semantic view: logical tables & relationships | Malloy sources and joins |
| Dimensions, facts, metrics | Dimensions, row-level facts, and measures — facts feed measures, so you can re-aggregate at any grain |
WITH SYNONYMS / COMMENT | #(doc) / #(index), indexed by the AI Analytics Engine |
| Verified queries | Parity fixtures and named views |
PUBLIC / PRIVATE, RBAC | Fine-grained access control in the model, versioned and enforced on every surface |
| Cortex Analyst / BI on top | Every surface — agents over MCP, data apps, notebooks, dashboards, APIs |
The Migration Flow
Credible reads the semantic view definition, translates logical tables and relationships to sources and joins (facts to row-level dimensions, metrics to measures), enriches with #(doc)/#(index) tags seeded from synonyms and comments, and — where you connect it — validates against Snowflake.
What Credible Handles
- Two coexisting formats — a deployment may use native
SEMANTIC VIEWobjects, legacy Cortex Analyst YAML on a stage, or both. Credible detects which and reads each accordingly. - Facts vs. metrics — a fact is a row-level expression; a metric is its aggregation. Credible keeps them distinct (fact → row-level dimension, metric → measure) so you can still re-aggregate at different grains. Collapsing them would lose that.
- Verified queries are the best thing to validate against — Credible replays each question→SQL pair and diffs the result against the migrated Malloy. (Verified SQL references logical names, not physical tables.)
Before & After
A CREATE SEMANTIC VIEW statement:
CREATE OR REPLACE SEMANTIC VIEW sales.sales_analytics
TABLES (
orders AS sales.orders PRIMARY KEY (order_id)
WITH SYNONYMS = ('purchase_orders')
COMMENT = 'Order transactions at the order grain',
customers AS sales.customers PRIMARY KEY (customer_id)
)
RELATIONSHIPS (
orders_to_customers AS orders (customer_id) REFERENCES customers (customer_id)
)
FACTS (
orders.line_amount AS orders.amount COMMENT = 'Per-row order amount in USD',
PRIVATE orders.is_shipped AS CASE WHEN orders.status = 'shipped' THEN 1 ELSE 0 END
)
DIMENSIONS (
orders.order_date AS CAST(orders.created_at AS DATE)
COMMENT = 'Date the order was placed',
customers.region AS customers.geographic_region
)
METRICS (
orders.total_revenue AS SUM(orders.line_amount) COMMENT = 'Total revenue in USD',
orders.shipped_revenue AS SUM(orders.line_amount * orders.is_shipped),
orders.shipped_revenue_pct AS
SUM(orders.line_amount * orders.is_shipped) / SUM(orders.line_amount)
);source: orders is conn.table('sales.orders') extend {
primary_key: order_id
join_one: customers is conn.table('sales.customers') on customer_id
dimension:
#(doc) Date the order was placed. Also known as: order_day
order_date is created_at::date
#(doc) Per-row order amount in USD (fact)
line_amount is amount
#(doc) Row-level shipped flag (fact)
is_shipped is pick 1 when status = 'shipped' else 0
measure:
#(doc) Total revenue in USD
# currency
total_revenue is sum(line_amount)
#(doc) Revenue from shipped orders
# currency
shipped_revenue is sum(line_amount) { where: status = 'shipped' }
#(doc) Share of revenue that shipped
# percent
shipped_revenue_pct is shipped_revenue / total_revenue
}FACTS become row-level dimensions that feed measures; METRICS become measures. WITH SYNONYMS and COMMENT fold into #(doc) (Malloy has no synonym primitive, so alternate names go in the description for retrieval), and PRIVATE facts map to access modifiers so they feed measures without being independently queryable.
More than a reformat. Semantic views map almost 1:1, so the gain is what surrounds them — composable follow-up queries, AI Analytics Engine discovery, and one model that reaches agents, apps, and BI beyond Cortex. See what you gain →