Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ profiles.yml

.ruff_cache
__pycache__
dbt_internal_packages/
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This is a sandbox project for exploring the basic functionality and latest featu

This README will guide you through setting up the project on dbt Cloud. Working through this example should give you a good sense of how dbt Cloud works and what's involved with setting up your own project. We'll also _optionally_ cover some intermediate topics like setting up Environments and Jobs in dbt Cloud, working with a larger dataset, and setting up pre-commit hooks if you'd like.

> [!NOTE]
> **The `main` is compatible with [dbt Fusion](https://docs.getdbt.com/docs/fusion/about-fusion).** and dbt Core v1.12 and higher. It uses the latest Semantic Layer YAML spec, with semantic models embedded in model YAML files, `type: simple` metrics replacing measures, and `type_params` promoted to top-level keys. If you're looking for the legacy project using the pre-Fusion YAML spec, check out the [`jaffle-shop-old`](../../tree/jaffle-shop-old) branch.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be the "main branch" instead of "the main"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also instead of "pre-Fusion YAML spec" we should talk about the "legacy YAML semantic layer spec"


> [!NOTE]
> This project is geared towards folks learning dbt Cloud with a cloud warehouse. If you're brand new to dbt, we recommend starting with the [dbt Learn](https://learn.getdbt.com/) platform. It's a free, interactive way to learn dbt, and it's a great way to get started if you're new to the tool. If you just want to try dbt locally as quickly as possible without setting up a data warehouse check out [`jaffle_shop_duckdb`](https://github.com/dbt-labs/jaffle_shop_duckdb).

Expand Down
3 changes: 3 additions & 0 deletions dbt_project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ models:
+materialized: view
marts:
+materialized: table

flags:
require_generic_test_arguments_property: true
84 changes: 37 additions & 47 deletions models/marts/customers.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
models:
- name: customers
description: Customer overview data mart, offering key details for each unique customer. One row per customer.
semantic_model:
enabled: true
agg_time_dimension: first_ordered_at
data_tests:
- dbt_utils.expression_is_true:
expression: "lifetime_spend_pretax + lifetime_tax_paid = lifetime_spend"
arguments:
expression: "lifetime_spend_pretax + lifetime_tax_paid = lifetime_spend"
columns:
- name: customer_id
description: The unique key of the orders mart.
data_tests:
- not_null
- unique
entity:
type: primary
name: customer
- name: customer_name
description: Customers' full name.
dimension:
type: categorical
- name: count_lifetime_orders
description: Total number of orders a customer has ever placed.
- name: first_ordered_at
description: The timestamp when a customer placed their first order.
granularity: day
dimension:
type: time
- name: last_ordered_at
description: The timestamp of a customer's most recent order.
granularity: day
dimension:
type: time
- name: lifetime_spend_pretax
description: The sum of all the pre-tax subtotals of every order a customer has placed.
- name: lifetime_tax_paid
Expand All @@ -28,72 +43,47 @@ models:
description: Options are 'new' or 'returning', indicating if a customer has ordered more than once or has only placed their first order to date.
data_tests:
- accepted_values:
values: ["new", "returning"]

semantic_models:
- name: customers
defaults:
agg_time_dimension: first_ordered_at
description: |
Customer grain mart.
model: ref('customers')
entities:
- name: customer
expr: customer_id
type: primary
dimensions:
- name: customer_name
type: categorical
- name: customer_type
type: categorical
- name: first_ordered_at
type: time
type_params:
time_granularity: day
- name: last_ordered_at
type: time
type_params:
time_granularity: day
measures:
arguments:
values: ["new", "returning"]
dimension:
type: categorical
metrics:
- name: customers
description: Count of unique customers
label: Customers
type: simple
agg: count_distinct
expr: customer_id
- name: count_lifetime_orders
description: Total count of orders per customer.
label: Count Lifetime Orders
type: simple
agg: sum
- name: lifetime_spend_pretax
description: Customer lifetime spend before taxes.
description: Customer's lifetime spend before tax
label: LTV Pre-tax
type: simple
agg: sum
- name: lifetime_spend
agg: sum
description: Gross customer lifetime spend inclusive of taxes.
label: Lifetime Spend
type: simple
agg: sum

metrics:
- name: lifetime_spend_pretax
description: Customer's lifetime spend before tax
label: LTV Pre-tax
type: simple
type_params:
measure: lifetime_spend_pretax
- name: count_lifetime_orders
description: Count of lifetime orders
label: Count Lifetime Orders
type: simple
type_params:
measure: count_lifetime_orders
- name: average_order_value
description: LTV pre-tax / number of orders
label: Average Order Value
type: derived
type_params:
metrics:
- count_lifetime_orders
- lifetime_spend_pretax
expr: lifetime_spend_pretax / count_lifetime_orders
expr: lifetime_spend_pretax / count_lifetime_orders
input_metrics:
- name: count_lifetime_orders
- name: lifetime_spend_pretax

saved_queries:
- name: customer_order_metrics
description: Key customer order metrics grouped by customer.
label: Customer Order Metrics
query_params:
metrics:
- count_lifetime_orders
Expand Down
34 changes: 18 additions & 16 deletions models/marts/locations.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
semantic_models:
models:
- name: locations
description: |
Location dimension table. The grain of the table is one row per location.
model: ref('locations')
defaults:
agg_time_dimension: opened_date
entities:
- name: location
type: primary
expr: location_id
dimensions:
semantic_model:
enabled: true
agg_time_dimension: opened_date
columns:
- name: location_id
entity:
type: primary
name: location
- name: location_name
type: categorical
dimension:
type: categorical
- name: opened_date
expr: opened_date
type: time
type_params:
time_granularity: day
measures:
granularity: day
dimension:
type: time
metrics:
- name: average_tax_rate
description: Average tax rate.
expr: tax_rate
label: Average Tax Rate
type: simple
agg: average
expr: tax_rate
29 changes: 17 additions & 12 deletions models/marts/metricflow_time_spine.sql
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
-- metricflow_time_spine.sql
with

days as (

--for BQ adapters use "DATE('01/01/2000','mm/dd/yyyy')"
{{ dbt_date.get_base_dates(n_dateparts=365*10, datepart="day") }}
{{
config(
materialized = 'table',
)
}}

with days as (

{{
dbt.date_spine(
'day',
"to_date('01/01/2000','mm/dd/yyyy')",
"to_date('01/01/2030','mm/dd/yyyy')"
)
}}

),

cast_to_date as (

final as (
select cast(date_day as date) as date_day

from days

)

select * from cast_to_date
select * from final
8 changes: 8 additions & 0 deletions models/marts/metricflow_time_spine.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
models:
- name: metricflow_time_spine
description: Time spine model used by MetricFlow for temporal joins and aggregations.
time_spine:
standard_granularity_column: date_day
columns:
- name: date_day
granularity: day
Loading
Loading