> ## Documentation Index
> Fetch the complete documentation index at: https://docs.credibledata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from dbt Semantic Layer

> Convert your dbt semantic models and MetricFlow metrics into governed Malloy semantic models

The dbt Semantic Layer already expresses your business in entities, dimensions, measures, and metrics — which maps unusually cleanly onto Malloy. Credible reads your MetricFlow definitions, flattens the measure/metric split into Malloy measures, and — where you connect it — validates each metric against the Semantic Layer's own query engine.

## What Credible Reads

Your **semantic models** (`semantic_models:` YAML — entities, dimensions, measures) and **metrics** (`metrics:` YAML — simple, ratio, derived, cumulative). The agent parses that project YAML directly — the fullest-fidelity input, since the YAML carries `expr`, `filter`, and `agg_time_dimension` details the compiled APIs abstract away. Connecting the official **dbt MCP server** (`get_metrics`, `get_dimensions`, `get_entities`, `execute_sql`) or the **Semantic Layer APIs** (GraphQL / JDBC / Python) is optional and adds live metric validation.

## What Comes Across

The everyday modeling carries over. Here's how the bigger pieces land — and where they get better:

| In dbt                                           | In Credible                                                                                                                                                  |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Semantic models (entities, dimensions, measures) | Malloy **sources**, joins, dimensions, and measures                                                                                                          |
| Metrics (simple / ratio / derived)               | Measures — no separate measure-vs-metric layer to maintain                                                                                                   |
| Cumulative metrics & `metric_time`               | Rebuilt as window views over explicit date fields                                                                                                            |
| Metric descriptions                              | `#(doc)` / `#(index)`, indexed by the [Context Engine](/how-to/analyzing/overview)                                                                           |
| Governance (none field-level today)              | **Fine-grained access control in the model**, versioned and enforced everywhere                                                                              |
| Semantic Layer API consumers                     | Directly queryable on every surface — agents over MCP, [data apps](/how-to/analyzing/data-apps), [notebooks](/how-to/analyzing/workspaces), dashboards, APIs |

## The Migration Flow

Credible [reads](/how-to/migrating/overview) the semantic models and metrics, translates entities to keys/joins and measures/metrics to Malloy measures, enriches with `#(doc)`/`#(index)` tags, and — where you connect it — validates by querying each metric through the Semantic Layer API at the same grain and diffing the results — MetricFlow owns SQL generation, so its result is the canonical number to match.

## What Credible Handles

* **The measure/metric split** flattens into one set of Malloy measures. A `simple` metric is often just a rename of its measure — Credible won't create two Malloy fields where one belongs.
* **`metric_time` and the time spine** have no Malloy equivalent. Credible chooses the concrete date field per view and truncates with `.month`/`.day`; cumulative metrics are rebuilt as view-level window calculations.
* **Derived and ratio metrics reference other metrics**, not columns. Credible resolves the dependency chain (metric → metric → measure → column) before writing the Malloy expression.

## Before & After

dbt semantic model and metrics:

```yaml theme={"languages":{"custom":["/languages/motly.tmGrammar.json","/languages/malloy.tmGrammar.json"]}}
semantic_models:
  - name: orders
    model: ref('fct_orders')
    defaults:
      agg_time_dimension: order_date
    entities:
      - name: order_id
        type: primary
      - name: customer
        type: foreign
        expr: customer_id
    dimensions:
      - name: order_date
        type: time
        type_params: { time_granularity: day }
      - name: status
        type: categorical
        expr: order_status
    measures:
      - name: order_total
        description: Sum of order amounts
        agg: sum
        expr: amount

metrics:
  - name: revenue
    type: simple
    type_params: { measure: order_total }
  - name: completed_revenue
    type: simple
    type_params: { measure: order_total }
    filter: "{{ Dimension('order__status') }} = 'completed'"
  - name: completion_rate
    type: ratio
    type_params: { numerator: completed_revenue, denominator: revenue }
```

```malloy theme={"languages":{"custom":["/languages/motly.tmGrammar.json","/languages/malloy.tmGrammar.json"]}}
source: orders is conn.table('analytics.fct_orders') extend {
  primary_key: order_id
  join_one: customers is conn.table('analytics.dim_customers') on customer_id

  dimension:
    #(doc) Order status
    #(index)
    status is order_status

  measure:
    #(doc) Total revenue (USD)
    # currency
    revenue is sum(amount)

    #(doc) Number of orders
    order_count is count(order_id)

    #(doc) Revenue from completed orders
    # currency
    completed_revenue is sum(amount) { where: status = 'completed' }

    #(doc) Share of revenue from completed orders
    # percent
    completion_rate is completed_revenue / revenue

  view:
    #(doc) Revenue by month
    revenue_by_month is {
      group_by: order_date.month
      aggregate: revenue
    }
}
```

The two `simple` metrics collapse into their measures rather than duplicating them; `completion_rate` becomes a straight ratio; and the Jinja `filter` becomes a `{ where: … }` on the measure.

**More than a reformat.** Your metrics become directly queryable and composable — not just a metrics API — AI-discoverable through the [Context Engine](/how-to/analyzing/overview), and deliverable to every surface. [See what you gain →](/how-to/migrating/overview#more-than-a-reformat)

## Next Steps

<CardGroup cols={2}>
  <Card title="Migration Overview" icon="diagram-project" color="#5C7A93" href="/how-to/migrating/overview">
    The method behind every migration
  </Card>

  <Card title="Metadata & Discovery" icon="tags" color="#94793A" href="/how-to/modeling/metadata-tags">
    Tune your migrated model for AI retrieval
  </Card>
</CardGroup>
