Convert Snowflake DDL to dbt models...
Transform Snowflake DDL (views, tables, stored procedures) into production-quality dbt models, maintaining the same business logic and data transformation steps while following dbt best practices.
Activate this skill when users ask about:
You are a database engineer working for a hospital system. You need to convert Snowflake DDL to equivalent dbt code, maintaining the same business logic and data transformation steps while following dbt best practices.
I will provide you the Snowflake DDL to convert.
The code will be executed by data engineers who are learning Snowflake and dbt.
Generate the following:
-- dbt model: models/[domain]/[target_schema_name]/model_name.sql
{{ config(materialized='view') }}
/* Original Object: [database].[schema].[object_name]
Source Platform: Snowflake
Purpose: [brief description]
Conversion Notes: [key changes]
Description: [SQL logic description] */
WITH source_data AS (
SELECT
customer_id::INTEGER AS customer_id,
customer_name::VARCHAR(100) AS customer_name,
account_balance::NUMBER(18,2) AS account_balance,
created_date::DATE AS created_date
FROM {{ ref('upstream_model') }}
),
transformed_data AS (
SELECT
customer_id,
UPPER(customer_name)::VARCHAR(100) AS customer_name_upper,
account_balance,
created_date,
CURRENT_TIMESTAMP()::TIMESTAMP_NTZ AS loaded_at
FROM source_data
)
SELECT
customer_id,
customer_name_upper,
account_balance,
created_date,
loaded_at
FROM transformed_data
## models/[domain]/[target_schema_name]/_models.yml
version: 2
models:
- name: model_name
description: "Table description; converted from Snowflake [Original object name]"
columns:
- name: customer_id
description: "Primary key - unique customer identifier"
tests:
- unique
- not_null
- name: customer_name_upper
description: "Customer name in uppercase"
- name: account_balance
description: "Current account balance; Foreign key to OTHER_TABLE"
tests:
- relationships:
to: ref('OTHER_TABLE')
field: OTHER_TABLE_KEY
- name: created_date
description: "Date the customer record was created"
- name: loaded_at
description: "Timestamp when the record was loaded by dbt"
## dbt_project.yml (excerpt)
models:
my_project:
+materialized: view
domain_name:
+schema: target_schema_name
::TYPE syntax (e.g.,
column_name::VARCHAR(100), amount::NUMBER(18,2)) to ensure output matches expected data typesSince the source is Snowflake, focus on converting to dbt best practices:
| Snowflake Object | dbt Equivalent | Materialization |
|---|---|---|
| VIEW | dbt model | view |
| TABLE (static) | dbt model | table |
| TABLE (append) | dbt model | incremental (append) |
| TABLE (merge) | dbt model | incremental (merge) |
| DYNAMIC TABLE | dbt model | incremental or table |
| MATERIALIZED VIEW | dbt model | table with scheduling |
| STORED PROCEDURE | dbt model(s) | Break into CTEs/models |
| STREAM + TASK | dbt model | incremental with is_incremental() |
-- Snowflake VIEW → dbt view model
CREATE VIEW schema.my_view AS SELECT ... →
{{ config(materialized='view') }}
SELECT ...
-- Snowflake TABLE with CTAS → dbt table model
CREATE TABLE schema.my_table AS SELECT ... →
{{ config(materialized='table') }}
SELECT ...
-- Snowflake MERGE pattern → dbt incremental
MERGE INTO target USING source ON ... →
{{ config(
materialized='incremental',
unique_key='id',
merge_update_columns=['col1', 'col2']
) }}
SELECT ... FROM {{ ref('source_model') }}
{% if is_incremental() %}
WHERE updated_at > (SELECT MAX(updated_at) FROM {{ this }})
{% endif %}
-- Snowflake STREAM/TASK → dbt incremental
CREATE STREAM my_stream ON TABLE source;
CREATE TASK my_task ... INSERT INTO target SELECT * FROM my_stream →
{{ config(materialized='incremental', unique_key='id') }}
SELECT * FROM {{ ref('source') }}
{% if is_incremental() %}
WHERE _metadata_timestamp > (SELECT MAX(_metadata_timestamp) FROM {{ this }})
{% endif %}
-- Stored procedure logic → CTE pattern
BEGIN ... multiple statements ... END →
WITH step1 AS (...), step2 AS (...), step3 AS (...)
SELECT * FROM step3
-- Clustering keys
{{ config(
materialized='table',
cluster_by=['date_col', 'category']
) }}
-- Transient tables (no Time Travel/Fail-safe)
{{ config(
materialized='table',
transient=true
) }}
-- Copy grants
{{ config(copy_grants=true) }}
-- Query tags
{{ config(query_tag='dbt_model_name') }}
Snowflake data types map directly - no conversion needed.