Amazon Redshift to dbt Model Conversion
Purpose
Transform Amazon Redshift DDL (views, tables, stored procedures) into production-quality dbt models
compatible with Snowflake, maintaining the same business logic and data transformation steps while
following dbt best practices.
When to Use This Skill
Activate this skill when users ask about:
- Converting Redshift views or tables to dbt models
- Migrating Redshift PL/pgSQL stored procedures to dbt
- Translating Redshift SQL syntax to Snowflake
- Generating schema.yml files with tests and documentation
- Handling Redshift-specific syntax (DISTKEY/SORTKEY, system catalogs, COPY/UNLOAD)
Task Description
You are a database engineer working for a hospital system. You need to convert Amazon Redshift DDL
to equivalent dbt code compatible with Snowflake, maintaining the same business logic and data
transformation steps while following dbt best practices.
Input Requirements
I will provide you the Redshift DDL to convert.
Audience
The code will be executed by data engineers who are learning Snowflake and dbt.
Output Requirements
Generate the following:
- One or more dbt models with complete SQL for every column
- A corresponding schema.yml file with appropriate tests and documentation
- A config block with materialization strategy
- Explanation of key changes and architectural decisions
- Inline comments highlighting any syntax that was converted
Conversion Guidelines
General Principles
- Replace procedural logic with declarative SQL where possible
- Break down complex procedures into multiple modular dbt models
- Implement appropriate incremental processing strategies
- Maintain data quality checks through dbt tests
- Use Snowflake SQL functions rather than macros whenever possible
Sample Response Format
-- dbt model: models/[domain]/[target_schema_name]/model_name.sql
{{ config(materialized='view') }}
/* Original Object: [database].[schema].[object_name]
Source Platform: Amazon Redshift
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,
-- TIMESTAMPTZ converted to TIMESTAMP_TZ
created_date::TIMESTAMP_TZ 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 Amazon Redshift [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
Specific Translation Rules
dbt Specific Requirements
- If the source is a view, use a view materialization in dbt
- Include appropriate dbt model configuration (materialization type)
- Add documentation blocks for a schema.yml
- Add descriptions for tables and columns
- Include relevant tests
- Define primary keys and relationships
- Assume that upstream objects are models
- Comprehensively provide all the columns in the output
- Break complex procedures into multiple models if needed
- Implement appropriate incremental strategies for large tables
- Use Snowflake SQL functions rather than macros whenever possible
- Always cast columns with explicit precision/scale using
::TYPE syntax (e.g.,
column_name::VARCHAR(100), amount::NUMBER(18,2)) to ensure output matches expected data types
- Always provide explicit column aliases for clarity and documentation
Performance Optimization
- Suggest clustering keys if needed
- Recommend materialization strategy (view vs table)
- Identify potential performance improvements
Redshift to Snowflake Syntax Conversion
- Remove DISTKEY/SORTKEY specifications (use clustering keys instead)
- Convert system catalog queries (pg**, stl*_, stv__) to Snowflake equivalents
- Replace COPY/UNLOAD with Snowflake COPY INTO
- Convert PL/pgSQL procedures to Snowflake Scripting
- Handle IDENTITY column differences
- Replace Redshift-specific date functions
- Convert APPROXIMATE COUNT DISTINCT to HLL functions
- Add inline SQL comments highlighting any syntax that was converted
Key Data Type Mappings
| Redshift |
Snowflake |
Notes |
| INT/INT2/INT4/INT8/INTEGER/BIGINT |
Same |
All alias to NUMBER |
| SMALLINT |
SMALLINT |
|
| DECIMAL/NUMERIC |
Same |
|
| FLOAT/FLOAT4/FLOAT8/REAL |
FLOAT |
|
| BOOL/BOOLEAN |
BOOLEAN |
|
| CHAR/VARCHAR/TEXT |
Same |
VARCHAR(MAX) → VARCHAR |
| BPCHAR |
VARCHAR |
|
| BINARY/VARBINARY/VARBYTE |
BINARY |
Max 8MB (vs 16MB Redshift) |
| DATE |
DATE |
|
| TIME/TIMETZ |
TIME |
Time zone not supported |
| TIMESTAMP/TIMESTAMPTZ |
TIMESTAMP/TIMESTAMP_TZ |
|
| INTERVAL types |
VARCHAR |
|
| GEOMETRY/GEOGRAPHY |
Same |
|
| SUPER |
VARIANT |
|
| HLLSKETCH |
Not supported |
Use HLL functions |
Key Syntax Conversions
-- DISTKEY/SORTKEY → Remove (use clustering keys)
CREATE TABLE t (id INT) DISTKEY(id) SORTKEY(created_at) →
CREATE TABLE t (id INT) CLUSTER BY (created_at)
-- COPY/UNLOAD → COPY INTO
COPY table FROM 's3://bucket/path' IAM_ROLE 'arn:...' →
COPY INTO table FROM @stage/path
-- System catalogs
pg_catalog.pg_tables → INFORMATION_SCHEMA.TABLES
stl_query → QUERY_HISTORY table function
stv_sessions → SHOW SESSIONS
-- GETDATE() → CURRENT_TIMESTAMP
GETDATE() → CURRENT_TIMESTAMP()
-- NVL → COALESCE
NVL(col, 0) → COALESCE(col, 0)
-- LISTAGG
LISTAGG(col, ',') WITHIN GROUP (ORDER BY col) →
LISTAGG(col, ',') WITHIN GROUP (ORDER BY col)
-- APPROXIMATE COUNT DISTINCT
APPROXIMATE COUNT(DISTINCT col) → APPROX_COUNT_DISTINCT(col)
Common Function Mappings
| Redshift |
Snowflake |
Notes |
NVL(a, b) |
NVL(a, b) or COALESCE(a, b) |
Same |
NVL2(a, b, c) |
IFF(a IS NOT NULL, b, c) |
|
COALESCE(...) |
COALESCE(...) |
Same |
NULLIF(a, b) |
NULLIF(a, b) |
Same |
GETDATE() |
CURRENT_TIMESTAMP() |
|
SYSDATE |
CURRENT_DATE() |
|
DATEADD(unit, n, d) |
DATEADD(unit, n, d) |
Same |
DATEDIFF(unit, d1, d2) |
DATEDIFF(unit, d1, d2) |
Same |
DATE_TRUNC(unit, d) |
DATE_TRUNC(unit, d) |
Same |
EXTRACT(part FROM d) |
EXTRACT(part FROM d) |
Same |
TO_CHAR(d, fmt) |
TO_CHAR(d, fmt) |
Same |
CONVERT(type, val) |
val::type |
|
LEN(str) |
LENGTH(str) |
|
CHARINDEX(s, str) |
POSITION(s IN str) |
|
LISTAGG(col, delim) |
LISTAGG(col, delim) |
Same |
APPROXIMATE COUNT(DISTINCT) |
APPROX_COUNT_DISTINCT() |
|
JSON_EXTRACT_PATH_TEXT() |
JSON_EXTRACT_PATH_TEXT() |
Same |
Dependencies
- List any upstream dependencies
- Suggest model organization in dbt project
Validation Checklist
- [] Every DDL statement has been accounted for in the dbt models
- [] SQL in models is compatible with Snowflake
- [] Redshift-specific syntax converted (DISTKEY/SORTKEY removed, system catalogs mapped)
- [] All business logic preserved
- [] All columns included in output
- [] Data types correctly mapped
- [] Functions translated to Snowflake equivalents
- [] Materialization strategy selected
- [] Tests added
- [] SQL logic description complete
- [] Table descriptions added
- [] Column descriptions added
- [] Dependencies correctly mapped
- [] Incremental logic (if applicable) verified
- [] Inline comments added for converted syntax
Related Skills
- $dbt-migration - For the complete migration workflow (discovery, planning, placeholder models,
testing, deployment)
- $dbt-modeling - For CTE patterns and SQL structure guidance
- $dbt-testing - For implementing comprehensive dbt tests
- $dbt-architecture - For project organization and folder structure
- $dbt-materializations - For choosing materialization strategies (view, table, incremental,
snapshots)
- $dbt-performance - For clustering keys, warehouse sizing, and query optimization
- $dbt-commands - For running dbt commands and model selection syntax
- $dbt-core - For dbt installation, configuration, and package management
- $snowflake-cli - For executing SQL and managing Snowflake objects
Supported Source Database
| Database |
Key Considerations |
| Amazon Redshift |
DISTKEY/SORTKEY, PL/pgSQL procedures, system catalogs (pg_, stl_, stv_), COPY/UNLOAD |
Translation References
Detailed syntax translation guides are available in the translation-references/ folder.
Copyright Notice: The translation reference documentation in this repository is derived from
Snowflake SnowConvert Documentation
and is © Copyright Snowflake Inc. All rights reserved. Used for reference purposes only.
Reference Index
- Basic Elements Literals
- Basic Elements
- Conditions
- Continue Handler
- Create Procedure
- Data Types
- ETL BI Repointing Power BI Redshift Repointing
- Exit Handler
- Expressions
- Functions
- Overview (README)
- Rs SQL Statements Select Into
- Rs SQL Statements Select
- SQL Statements Create Table As
- SQL Statements Create Table
- SQL Statements
- Subqueries
- System Catalog
1---2name: dbt-migration-redshift3description: Convert Amazon Redshift DDL to dbt models compatible with Snowflake. This skill should be used when converting views, tables, or stored procedures from Redshift to dbt code, generating schema.yml files with tests and documentation, or migrating Redshift SQL to follow dbt best practices.4---5
6# Amazon Redshift to dbt Model Conversion
7
8## Purpose
9
10Transform Amazon Redshift DDL (views, tables, stored procedures) into production-quality dbt models
11compatible with Snowflake, maintaining the same business logic and data transformation steps while
12following dbt best practices.
13
14## When to Use This Skill
15
16Activate this skill when users ask about:
17
18- Converting Redshift views or tables to dbt models
19- Migrating Redshift PL/pgSQL stored procedures to dbt
20- Translating Redshift SQL syntax to Snowflake
21- Generating schema.yml files with tests and documentation
22- Handling Redshift-specific syntax (DISTKEY/SORTKEY, system catalogs, COPY/UNLOAD)
23
24---
25
26## Task Description
27
28You are a database engineer working for a hospital system. You need to convert Amazon Redshift DDL
29to equivalent dbt code compatible with Snowflake, maintaining the same business logic and data
30transformation steps while following dbt best practices.
31
32## Input Requirements
33
34I will provide you the Redshift DDL to convert.
35
36## Audience
37
38The code will be executed by data engineers who are learning Snowflake and dbt.
39
40## Output Requirements
41
42Generate the following:
43
441. One or more dbt models with complete SQL for every column
452. A corresponding schema.yml file with appropriate tests and documentation
463. A config block with materialization strategy
474. Explanation of key changes and architectural decisions
485. Inline comments highlighting any syntax that was converted
49
50## Conversion Guidelines
51
52### General Principles
53
54- Replace procedural logic with declarative SQL where possible
55- Break down complex procedures into multiple modular dbt models
56- Implement appropriate incremental processing strategies
57- Maintain data quality checks through dbt tests
58- Use Snowflake SQL functions rather than macros whenever possible
59
60### Sample Response Format
61
62```sql
63-- dbt model: models/[domain]/[target_schema_name]/model_name.sql
64{{ config(materialized='view') }}
65
66/* Original Object: [database].[schema].[object_name]
67 Source Platform: Amazon Redshift
68 Purpose: [brief description]
69 Conversion Notes: [key changes]
70 Description: [SQL logic description] */
71
72WITH source_data AS (
73 SELECT
74 customer_id::INTEGER AS customer_id,
75 customer_name::VARCHAR(100) AS customer_name,
76 account_balance::NUMBER(18,2) AS account_balance,
77 -- TIMESTAMPTZ converted to TIMESTAMP_TZ
78 created_date::TIMESTAMP_TZ AS created_date
79 FROM {{ ref('upstream_model') }}
80),
81
82transformed_data AS (
83 SELECT
84 customer_id,
85 UPPER(customer_name)::VARCHAR(100) AS customer_name_upper,
86 account_balance,
87 created_date,
88 CURRENT_TIMESTAMP()::TIMESTAMP_NTZ AS loaded_at
89 FROM source_data
90)
91
92SELECT
93 customer_id,
94 customer_name_upper,
95 account_balance,
96 created_date,
97 loaded_at
98FROM transformed_data
99```
100
101```yaml
102## models/[domain]/[target_schema_name]/_models.yml
103version: 2
104
105models:
106 - name: model_name
107 description: "Table description; converted from Amazon Redshift [Original object name]"
108 columns:
109 - name: customer_id
110 description: "Primary key - unique customer identifier"
111 tests:
112 - unique
113 - not_null
114 - name: customer_name_upper
115 description: "Customer name in uppercase"
116 - name: account_balance
117 description: "Current account balance; Foreign key to OTHER_TABLE"
118 tests:
119 - relationships:
120 to: ref('OTHER_TABLE')
121 field: OTHER_TABLE_KEY
122 - name: created_date
123 description: "Date the customer record was created"
124 - name: loaded_at
125 description: "Timestamp when the record was loaded by dbt"
126```
127
128```yaml
129## dbt_project.yml (excerpt)
130models:
131 my_project:
132 +materialized: view
133 domain_name:
134 +schema: target_schema_name
135```
136
137### Specific Translation Rules
138
139#### dbt Specific Requirements
140
141- If the source is a view, use a view materialization in dbt
142- Include appropriate dbt model configuration (materialization type)
143- Add documentation blocks for a schema.yml
144- Add descriptions for tables and columns
145- Include relevant tests
146- Define primary keys and relationships
147- Assume that upstream objects are models
148- Comprehensively provide all the columns in the output
149- Break complex procedures into multiple models if needed
150- Implement appropriate incremental strategies for large tables
151- Use Snowflake SQL functions rather than macros whenever possible
152- **Always cast columns with explicit precision/scale** using `::TYPE` syntax (e.g.,
153 `column_name::VARCHAR(100)`, `amount::NUMBER(18,2)`) to ensure output matches expected data types
154- **Always provide explicit column aliases** for clarity and documentation
155
156#### Performance Optimization
157
158- Suggest clustering keys if needed
159- Recommend materialization strategy (view vs table)
160- Identify potential performance improvements
161
162#### Redshift to Snowflake Syntax Conversion
163
164- Remove DISTKEY/SORTKEY specifications (use clustering keys instead)
165- Convert system catalog queries (pg*\*, stl*\_, stv\_\_) to Snowflake equivalents
166- Replace COPY/UNLOAD with Snowflake COPY INTO
167- Convert PL/pgSQL procedures to Snowflake Scripting
168- Handle IDENTITY column differences
169- Replace Redshift-specific date functions
170- Convert APPROXIMATE COUNT DISTINCT to HLL functions
171- Add inline SQL comments highlighting any syntax that was converted
172
173#### Key Data Type Mappings
174
175| Redshift | Snowflake | Notes |
176| --------------------------------- | ---------------------- | -------------------------- |
177| INT/INT2/INT4/INT8/INTEGER/BIGINT | Same | All alias to NUMBER |
178| SMALLINT | SMALLINT | |
179| DECIMAL/NUMERIC | Same | |
180| FLOAT/FLOAT4/FLOAT8/REAL | FLOAT | |
181| BOOL/BOOLEAN | BOOLEAN | |
182| CHAR/VARCHAR/TEXT | Same | VARCHAR(MAX) → VARCHAR |
183| BPCHAR | VARCHAR | |
184| BINARY/VARBINARY/VARBYTE | BINARY | Max 8MB (vs 16MB Redshift) |
185| DATE | DATE | |
186| TIME/TIMETZ | TIME | Time zone not supported |
187| TIMESTAMP/TIMESTAMPTZ | TIMESTAMP/TIMESTAMP_TZ | |
188| INTERVAL types | VARCHAR | |
189| GEOMETRY/GEOGRAPHY | Same | |
190| SUPER | VARIANT | |
191| HLLSKETCH | Not supported | Use HLL functions |
192
193#### Key Syntax Conversions
194
195```sql
196-- DISTKEY/SORTKEY → Remove (use clustering keys)
197CREATE TABLE t (id INT) DISTKEY(id) SORTKEY(created_at) →
198CREATE TABLE t (id INT) CLUSTER BY (created_at)
199
200-- COPY/UNLOAD → COPY INTO
201COPY table FROM 's3://bucket/path' IAM_ROLE 'arn:...' →
202COPY INTO table FROM @stage/path
203
204-- System catalogs
205pg_catalog.pg_tables → INFORMATION_SCHEMA.TABLES
206stl_query → QUERY_HISTORY table function
207stv_sessions → SHOW SESSIONS
208
209-- GETDATE() → CURRENT_TIMESTAMP
210GETDATE() → CURRENT_TIMESTAMP()
211
212-- NVL → COALESCE
213NVL(col, 0) → COALESCE(col, 0)
214
215-- LISTAGG
216LISTAGG(col, ',') WITHIN GROUP (ORDER BY col) →
217LISTAGG(col, ',') WITHIN GROUP (ORDER BY col)
218
219-- APPROXIMATE COUNT DISTINCT
220APPROXIMATE COUNT(DISTINCT col) → APPROX_COUNT_DISTINCT(col)
221```
222
223#### Common Function Mappings
224
225| Redshift | Snowflake | Notes |
226| ----------------------------- | ------------------------------- | ----- |
227| `NVL(a, b)` | `NVL(a, b)` or `COALESCE(a, b)` | Same |
228| `NVL2(a, b, c)` | `IFF(a IS NOT NULL, b, c)` | |
229| `COALESCE(...)` | `COALESCE(...)` | Same |
230| `NULLIF(a, b)` | `NULLIF(a, b)` | Same |
231| `GETDATE()` | `CURRENT_TIMESTAMP()` | |
232| `SYSDATE` | `CURRENT_DATE()` | |
233| `DATEADD(unit, n, d)` | `DATEADD(unit, n, d)` | Same |
234| `DATEDIFF(unit, d1, d2)` | `DATEDIFF(unit, d1, d2)` | Same |
235| `DATE_TRUNC(unit, d)` | `DATE_TRUNC(unit, d)` | Same |
236| `EXTRACT(part FROM d)` | `EXTRACT(part FROM d)` | Same |
237| `TO_CHAR(d, fmt)` | `TO_CHAR(d, fmt)` | Same |
238| `CONVERT(type, val)` | `val::type` | |
239| `LEN(str)` | `LENGTH(str)` | |
240| `CHARINDEX(s, str)` | `POSITION(s IN str)` | |
241| `LISTAGG(col, delim)` | `LISTAGG(col, delim)` | Same |
242| `APPROXIMATE COUNT(DISTINCT)` | `APPROX_COUNT_DISTINCT()` | |
243| `JSON_EXTRACT_PATH_TEXT()` | `JSON_EXTRACT_PATH_TEXT()` | Same |
244
245#### Dependencies
246
247- List any upstream dependencies
248- Suggest model organization in dbt project
249
250---
251
252## Validation Checklist
253
254- [] Every DDL statement has been accounted for in the dbt models
255- [] SQL in models is compatible with Snowflake
256- [] Redshift-specific syntax converted (DISTKEY/SORTKEY removed, system catalogs mapped)
257- [] All business logic preserved
258- [] All columns included in output
259- [] Data types correctly mapped
260- [] Functions translated to Snowflake equivalents
261- [] Materialization strategy selected
262- [] Tests added
263- [] SQL logic description complete
264- [] Table descriptions added
265- [] Column descriptions added
266- [] Dependencies correctly mapped
267- [] Incremental logic (if applicable) verified
268- [] Inline comments added for converted syntax
269
270---
271
272## Related Skills
273
274- $dbt-migration - For the complete migration workflow (discovery, planning, placeholder models,
275 testing, deployment)
276- $dbt-modeling - For CTE patterns and SQL structure guidance
277- $dbt-testing - For implementing comprehensive dbt tests
278- $dbt-architecture - For project organization and folder structure
279- $dbt-materializations - For choosing materialization strategies (view, table, incremental,
280 snapshots)
281- $dbt-performance - For clustering keys, warehouse sizing, and query optimization
282- $dbt-commands - For running dbt commands and model selection syntax
283- $dbt-core - For dbt installation, configuration, and package management
284- $snowflake-cli - For executing SQL and managing Snowflake objects
285
286---
287
288## Supported Source Database
289
290| Database | Key Considerations |
291| ------------------- | --------------------------------------------------------------------------------------- |
292| **Amazon Redshift** | DISTKEY/SORTKEY, PL/pgSQL procedures, system catalogs (pg\_, stl\_, stv\_), COPY/UNLOAD |
293
294## Translation References
295
296Detailed syntax translation guides are available in the `translation-references/` folder.
297
298> **Copyright Notice:** The translation reference documentation in this repository is derived from
299> [Snowflake SnowConvert Documentation](https://docs.snowflake.com/en/migrations/snowconvert-docs)
300> and is © Copyright Snowflake Inc. All rights reserved. Used for reference purposes only.
301
302### Reference Index
303
304- [Basic Elements Literals](translation-references/redshift-basic-elements-literals.md)
305- [Basic Elements](translation-references/redshift-basic-elements.md)
306- [Conditions](translation-references/redshift-conditions.md)
307- [Continue Handler](translation-references/redshift-continue-handler.md)
308- [Create Procedure](translation-references/redshift-create-procedure.md)
309- [Data Types](translation-references/redshift-data-types.md)
310- [ETL BI Repointing Power BI Redshift Repointing](translation-references/redshift-etl-bi-repointing-power-bi-redshift-repointing.md)
311- [Exit Handler](translation-references/redshift-exit-handler.md)
312- [Expressions](translation-references/redshift-expressions.md)
313- [Functions](translation-references/redshift-functions.md)
314- [Overview (README)](translation-references/redshift-readme.md)
315- [Rs SQL Statements Select Into](translation-references/redshift-rs-sql-statements-select-into.md)
316- [Rs SQL Statements Select](translation-references/redshift-rs-sql-statements-select.md)
317- [SQL Statements Create Table As](translation-references/redshift-sql-statements-create-table-as.md)
318- [SQL Statements Create Table](translation-references/redshift-sql-statements-create-table.md)
319- [SQL Statements](translation-references/redshift-sql-statements.md)
320- [Subqueries](translation-references/redshift-subqueries.md)
321- [System Catalog](translation-references/redshift-system-catalog.md)