No items found.

Why do I need Snowflake’s dbt Projects and DCM Projects?

Stop managing Snowflake infrastructure with error-prone scripts. See how DCM Projects handle the foundation so dbt can focus on answering business questions.

Table of contents
Partner with
Aimpoint Digital
Meet an Expert

dbt models need a DCM Foundation so they can finally focus on Answering Business Questions

dbt is a great tool for engineering data within a platform, but many talented engineering teams are still facing challenges building the foundation that dbt requires. Even with a mature dbt installation that transforms data efficiently, the infrastructure of warehouses, roles, dynamic tables, and ingestion is still managed by imperative, error-prone scripts or click-ops in non-SQL languages. 

Today’s teams still have a heavy lift before they can get to "outcome-based analytics" and are held back over and over by the challenges of cleanly aligning multiple environments (such as dev, UAT and production). The transformation logic (dbt) is world-class, but issues with the foundation it sits on can make it difficult to predict when changes will break a critical business process, and a team’s ability to support high-quality engineering in a clean environment is diminished.

Enter Snowflake DCM (Database Change Management) Projects. If dbt (dbt Projects in Snowflake) is the architect designing the interior of your house (the models, tests, and business logic), DCM Projects are the civil engineers pouring the concrete foundation and framing the walls (the infrastructure, ingestion pipelines, and governance). By separating these, you unlock a new tier of reliability. DCM Projects allow you to declaratively define your ingestion and infrastructure state, while dbt Projects focuses exclusively on transformation and business semantics. This separation isn’t just clean engineering; it’s the prerequisite for true outcome-based analytics where every line of code traces back to a business question.

Use Cases and Advantages

Example DCM Projects Use Case: Quick Environment Setup

DCM Projects can be used to create a copy of a Production database from an internal share. This results in a duplicate of the database with the same schemas and tables, but releases it from the restrictions of a share to allow further changes. One use of such a duplicate is to refresh non-prod environments with cuts of production-grade data, supporting further development initiatives.

A clear benefit is that data quality tests can be accurately performed within UAT before deploying new code into production, as developers can leverage accurate data instead of an outdated code base. For example, you could create a new database to test whether an innovation using AI principles is feasible or not, using appropriate and accurate data.

This also opens the door for a modern development approach, introducing and deploying branch-based environments instead of a fixed DEV environment that is shared between different initiatives.

Example dbt Projects Use Case: Extend existing Gold-tier for pre-reasoned Analytics layer

dbt Project transformations can be used to provide consistent business logic and semantics, curated by domain owners and members of the business, leveraging Gold-tier data across multiple Data Products to create a standardized and trustworthy output.

That output can now come in the form of Snowflake Semantic Views, fully managed through dbt. This functionality allows report developers to create new content without being bogged down navigating tooling limitations or redefining business logic, while also enabling general users to ask natural language questions of their data through CoWork; all using data and field definitions that have business-level sign-off.

In a previous project, I have used this approach to establish a common reporting repository that served multiple reporting tools, mobile users, second-layer ML workloads, and natural language prompt users in CoWork; all with a single solution.

The Great Separation: DCM for Infrastructure, dbt for Logic

The most common architectural mistake in 2026 is blurring the line between managing objects and transforming data. DCM Projects and dbt Projects have distinct, non-overlapping “best use” zones.

DCM Projects are your Infrastructure-as-Code (IaC) engine. Their sole purpose is to manage the existence and configuration of Snowflake objects.  Use DCM to define databases, schemas, warehouses, roles, grants, and critically the ingestion layer including Dynamic Tables, external stages, and tasks to handle any scheduled work that sits outside the downstream refresh chain. DCM’s “plan-then-deploy” workflow ensures that your production environment never drifts from your defined state. It answers the question: “What objects must exist for our data to flow?”

When files land in object storage, a Snowflake Stream tracks what's new, but reading a stream directly consumes it, which means tools like dbt can't query it safely without losing data. To address this, a Dynamic Table acts as the designated consumer.  It absorbs the stream's changes and persists them as a normal, queryable table in the staging schema. From dbt's perspective, it's just a table and the stream never existed. This separation is intentional so that DCM owns and manages the ingestion mechanics, while dbt stays focused purely on transformation, reading a stable surface it can query repeatedly without side effects.  This pattern also unlocks one of Snowflake's more powerful native capabilities, which is the ability to query files sitting directly in S3 without ever moving them first.

dbt Projects are your Transformation-as-Code engine. Once DCM has ensured the raw tables and dynamic tables exist, dbt takes over. Use dbt to take those initial objects and develop the transformation pipelines that clean, combine and model your data, defining the logic inside those objects. This is where you implement your business rules, KPIs, and semantic models. dbt answers the question: “How do we turn raw data into business answers?”

DCM Projects Best Uses: The “Container” Strategy (With Code)

Avoid using DCM to write complex SQL transformations. Instead, use it to build the containers and conveyor belts that feed the downstream dbt Projects.

1. The Manifest: Defining Environments

Everything starts with manifest.yml. This file defines your targets (DEV, PROD) and injects variables like {{env_suffix}} to automatically namespace your objects.

# manifest.yml
manifest_version: 2
type: DCM_PROJECT
default_target: DEV
targets:
DEV:
account: "myorg-dev"
project: "analytics_dcm"
owner_role: "ENGINEERING_ROLE"
templating:
env_suffix: "_DEV"
wh_size: "X-SMALL"
 
PROD:
account: "myorg-prod"
project: "analytics_dcm"
owner_role: "ENGINEERING_ROLE"
templating:
env_suffix: ""
wh_size: "SMALL"

2. Declarative Ingestion & Infrastructure

In your sources/definitions/ folder, you define the infrastructure. Notice how Dynamic Tables are defined here to handle ingestion, using INITIALIZE = ON_SCHEDULE for fast, non-blocking deployments.

The new DEFINE command performs a CREATE or ALTER and handles schema drift, only making specific changes when necessary.

-- sources/definitions/infrastructure.sql
 
-- 1. Define the Database and Schema
DEFINE DATABASE analytics{{env_suffix}}
COMMENT = 'Outcome-based Analytics Data';
DEFINE SCHEMA analytics{{env_suffix}}.raw;
DEFINE SCHEMA analytics{{env_suffix}}.staging;
 
-- 2. Define the Compute
DEFINE WAREHOUSE transform_wh{{env_suffix}}
WITH warehouse_size = '{{wh_size}}'
auto_suspend = 300;
 
-- 3. Define the Ingestion Layer (Dynamic Tables)
-- DCM manages the refresh logic, dbt just reads the result
DEFINE DYNAMIC TABLE analytics{{env_suffix}}.staging.user_events_raw
WAREHOUSE = transform_wh{{env_suffix}}
TARGET_LAG = 'DOWNSTREAM'
INITIALIZE = 'ON_SCHEDULE'
DATA_METRIC_SCHEDULE = 'TRIGGER_ON_CHANGES'
AS
SELECT
event_id,
user_id,
event_type,
event_timestamp,
source_system
FROM analytics{{env_suffix}}.raw.external_events_stream;   

dbt Project Best Uses: The “Outcome” Strategy (With Code)

With the infrastructure stabilized by DCM, your dbt project becomes a pure expression of business logic.

1. Sourcing DCM Objects

In sources.yml, you simply point to the tables DCM created. You don't create them; you trust they exist.

# models/staging/sources.yml
 
version: 2
sources:
- name: dcm_staging
database: analytics{{ env_var('DBT_ENV_SUFFIX', '_DEV') }}
schema: staging
tables:
- name: user_events_raw
description: "Raw event stream ingested and managed by DCM Project"
columns:
- name: event_id
tests: [unique, not_null]

2. Transformation & Semantic Definition

dbt models can focus entirely on the business question. This example demonstrates the logic for “User Retention” and defines it as a Semantic View for Cortex.

-- models/marts/user_retention.sql
 
{{ config(materialized='table') }}
-- Business Logic: Calculate retention cohorts
SELECT
date_trunc('month', first_event_date) as cohort_month,
user_id,
datediff('month', first_event_date, current_date) as months_since_signup,
case when last_event_date >= dateadd('month', 1, first_event_date) then 1 else 0 end as retained_month_1
FROM {{ source('dcm_staging', 'user_events_raw') }}
QUALIFY ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY first_event_date) = 1

3. The Semantic Layer (YAML)

Finally, expose this logic to the business via a Semantic View YAML (deployed via dbt or CoCo), linking directly to the outcome.

# semantic_views/user_retention_view.yaml
 
name: user_retention_analytics
description: "Outcome-based model for tracking user retention by cohort"
tables:
- name: retention_cohorts
base_table:
database: analytics{{ env_var('DBT_ENV_SUFFIX', '_DEV') }}
schema: marts
table: user_retention
dimensions:
- name: cohort_month
expr: cohort_month
data_type: DATE
- name: months_since_signup
expr: months_since_signup
data_type: NUMBER
metrics:
- name: retention_rate
description: "Percentage of users retained after N months"
expr: AVG(retained_month_1) * 100
data_type: NUMBER
verified_queries:
- name: cohort_performance
question: "What is the retention rate for users who signed up in January?"
sql: |
SELECT cohort_month, retention_rate
FROM user_retention_analytics
WHERE cohort_month = '2026-01-01'

Mapping the Flow: From Business Question to Deployed Code

To implement outcome-based analytics, you must trace a business question backward through dbt and DCM.

The Business Question: “Which marketing channels drive the highest retention?”

Step 1: The Outcome Layer (dbt). You start here. In your dbt project, you define a semantic model marketing_retention (as seen in the YAML above) that calculates retention by channel.

Step 2: The Ingestion Layer (DCM). Where does the data come from? A Dynamic Table defined in your DCM Project.

-- DCM handles the heavy lifting of joining raw streams
DEFINE DYNAMIC TABLE analytics{{env_suffix}}.staging.marketing_touchpoints
WAREHOUSE = transform_wh{{env_suffix}}
TARGET_LAG = '1 hour'
INITIALIZE = 'ON_SCHEDULE'
AS
SELECT
u.user_id,
m.channel,
m.touchpoint_date
FROM analytics{{env_suffix}}.raw.users u
JOIN analytics{{env_suffix}}.raw.marketing_logs m ON u.user_id = m.user_id;    

Step 3: The Infrastructure Layer (DCM). Does the database exist? Is the warehouse sized correctly? DCM defines these.

-- DCM ensures the container exists before dbt runs
DEFINE DATABASE analytics{{env_suffix}};
DEFINE WAREHOUSE transform_wh{{env_suffix}} WITH warehouse_size = '{{wh_size}}';

This flow ensures that when a business question changes, you update the dbt logic. When the scale or source changes, you update the DCM definition. The separation prevents “infrastructure drift” from breaking your carefully crafted business logic.

Integrating with Horizon: The Semantic Substrate

The separation of DCM and dbt becomes supercharged when layered with Horizon Catalog and Horizon Context.

  • Horizon Catalog ingests the lineage from both layers. It sees the DCM-defined Dynamic Table (marketing_touchpoints) feeding the dbt-defined model (user_retention). This provides end-to-end lineage from the raw log to the final dashboard metric.
  • Horizon Context enriches this lineage with business meaning. It pulls the semantic definitions from your dbt YAML and the technical metadata from your DCM objects. When a stakeholder asks Cortex Analyst, “Show me retention by channel,” the agent uses Horizon Context to understand that “retention” is a dbt metric built on top of a DCM-managed Dynamic Table.

Your First Steps: A Migration Checklist

Ready to divide and conquer in 5 easy steps?

  1. Audit Your Scripts
    Identify all imperative SQL scripts creating warehouses, roles, or dynamic tables. These are candidates for DCM.
  2. Initialize a DCM Project
    Create a manifest.yml and start defining your foundational objects.
  3. Migrate Ingestion
    Move your raw data ingestion logic (especially Dynamic Tables) into DCM definition files using DEFINE DYNAMIC TABLE.
  4. Refactor dbt
    Update your sources.yml to point to the new DCM-managed tables. Remove any "infrastructure" macros from dbt that create tables or warehouses.
  5. Connect Horizon
    Ensure both your DCM and dbt projects are registered in Horizon Catalog to visualize the full lineage

Conclusion

By separating infrastructure/ingestion with DCM Projects from transformation/logic in dbt Projects, you stop fighting your pipeline and start using dbt to do what it was meant to do:- answer business questions.

Our Expertise

Aimpoint Digital is both a Snowflake Elite Tier services partner and a dbt Labs Visionary Consulting and Services Partner. We also have 4 Snowflake Data Superheroes, which allows us an unusually high level of access to new Snowflake developments and preview functionality; including early access to further functionality for DCM Projects. We have the capability and passion to support your Snowflake deployments and pipeline development at scale. We also love a challenge and thrive on tackling complex scenarios.

If you’d like to explore how to strengthen your infrastructure deployment through DCM Projects, or accelerate your company’s dbt pipelines with Snowflake, get in touch!

Author
Angie Harney
Angie Harney
Snowflake Solutions Architect
Read Bio

Related reading

No items found.

Let's talk AI & data. We'll architect what's next.

Whether you need advanced AI solutions, strategic data expertise, or tailored insights, our team is here to help.

Meet an Expert