anfra docs
Semantic layer

Data models

Map a table or SQL query into dimensions and measures

A data model maps a database table (or a SQL query) into a structure anfra can reason about — its dimensions (raw, non-aggregated fields) and measures (aggregations scoped to this one model).

From database tables to metrics
  • Warehouse
  • public.orders — Raw orders table
  • public.customers — Raw customers table
  • Semantic layer
  • orders — Data model: dimensions + measures
  • customers — Data model: dimensions + measures
  • ecommerce dataset — Joins models via relationships
  • Query — Cross-model aggregation on the dataset
  • Visualization — Chart or table generated from the query result
  • table-orders → model-orders (map)
  • table-customers → model-customers (map)
  • model-orders → dataset
  • model-customers → dataset
  • dataset → metric (aggregate)
  • metric → visualization (generate)

Defining a data model

Put each model in its own .aml file under models/:

models/orders.model.aml
Model orders {
  type: 'table'
  label: 'Orders'
  data_source_name: 'warehouse'
  table_name: '"public"."orders"'

  dimension id {
    label: 'Id'
    type: 'number'
    definition: @sql {{ #SOURCE.id }};;
  }

  dimension status {
    label: 'Status'
    type: 'text'
    definition: @sql {{ #SOURCE.status }};;
  }

  measure order_count {
    label: 'Order Count'
    type: 'number'
    definition: @aql count(orders.id);;
  }
}
  • data_source_name is a connection from .anfra/data_sources.yml.
  • table_name is the table as the warehouse names it, quoted as its SQL dialect expects.
  • Every dimension and measure needs a label and a type. An optional description tells readers and agents what the field means.
  • {{ #SOURCE.column }} refers to a column of the model's table.

Dimensions vs. measures

  • Dimensions — raw values used for filtering and grouping, e.g. status, created_at, customer_id.
  • Measures — aggregations (count, sum, avg, …) computed within this single model.

Measures work well for aggregations that only need one model. Once you need to aggregate across multiple joined models, define a metric on a dataset instead.

Relationships

Models don't declare joins themselves. The dataset that includes them does, so the same model can be reused in several datasets. Include the key columns used for joins, such as id and customer_id, as dimensions on the model.

When to create a new data model

Create one data model per table or view you want to expose to the semantic layer. Keep models close to the underlying schema — leave cross-model logic to datasets.

Next steps

On this page