PostgreSQL/Greenplum/Netezza to dbt Model Conversion
Purpose
Transform PostgreSQL/Greenplum/Netezza 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 PostgreSQL/Greenplum/Netezza views or tables to dbt models
- Migrating PostgreSQL stored procedures to dbt
- Translating PostgreSQL syntax to Snowflake
- Generating schema.yml files with tests and documentation
- Handling PostgreSQL-specific syntax conversions (array expressions, CHAR padding, psql commands)
Task Description
You are a database engineer working for a hospital system. You need to convert
PostgreSQL/Greenplum/Netezza 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 PostgreSQL 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: PostgreSQL/Greenplum/Netezza
Purpose: [brief description]
Conversion Notes: [key changes]
Description: [SQL logic description] */
WITH source_data AS (
SELECT
-- SERIAL converted to INTEGER (use IDENTITY in table)
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 PostgreSQL [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
PostgreSQL to Snowflake Syntax Conversion
- Convert array expressions (<> ALL, = ANY) to Snowflake equivalents
- Handle CHAR padding differences
- Replace psql commands with SnowSQL equivalents
- Convert distribution keys (Greenplum) to clustering keys
- Handle string comparison behavior differences
- Convert PL/pgSQL to Snowflake Scripting
- Replace PostgreSQL-specific operators
- Handle SERIAL/BIGSERIAL with IDENTITY
Key Data Type Mappings
| PostgreSQL |
Snowflake |
Notes |
| INTEGER/INT/INT4 |
INTEGER |
|
| BIGINT/INT8 |
BIGINT |
|
| SMALLINT/INT2 |
SMALLINT |
|
| SERIAL/BIGSERIAL |
IDENTITY |
Use AUTOINCREMENT |
| NUMERIC/DECIMAL |
NUMERIC |
|
| REAL/FLOAT4 |
FLOAT |
|
| DOUBLE PRECISION/FLOAT8 |
FLOAT |
|
| BOOLEAN/BOOL |
BOOLEAN |
|
| CHAR/VARCHAR/TEXT |
Same |
|
| BYTEA |
BINARY |
|
| DATE |
DATE |
|
| TIME/TIMETZ |
TIME |
Time zone not supported |
| TIMESTAMP/TIMESTAMPTZ |
TIMESTAMP/TIMESTAMP_TZ |
|
| INTERVAL |
VARCHAR |
|
| JSON/JSONB |
VARIANT |
|
| ARRAY |
ARRAY |
|
| UUID |
VARCHAR |
|
Key Syntax Conversions
-- SERIAL -> AUTOINCREMENT
id SERIAL PRIMARY KEY -> id INT AUTOINCREMENT PRIMARY KEY
-- Array expressions
col <> ALL(ARRAY[1,2,3]) -> NOT ARRAY_CONTAINS(col, ARRAY_CONSTRUCT(1,2,3))
col = ANY(ARRAY[1,2,3]) -> ARRAY_CONTAINS(col, ARRAY_CONSTRUCT(1,2,3))
-- psql commands -> SnowSQL
\d table -> DESCRIBE TABLE table
\dt -> SHOW TABLES
-- generate_series -> TABLE(GENERATOR())
generate_series(1, 10) -> TABLE(GENERATOR(ROWCOUNT => 10))
-- NOW() -> CURRENT_TIMESTAMP
NOW() -> CURRENT_TIMESTAMP()
Common Function Mappings
| PostgreSQL |
Snowflake |
Notes |
COALESCE(...) |
COALESCE(...) |
Same |
NULLIF(a, b) |
NULLIF(a, b) |
Same |
NOW() |
CURRENT_TIMESTAMP() |
|
CURRENT_DATE |
CURRENT_DATE() |
Add parentheses |
CURRENT_TIMESTAMP |
CURRENT_TIMESTAMP() |
Add parentheses |
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 |
TO_DATE(s, fmt) |
TO_DATE(s, fmt) |
Same |
TO_NUMBER(s, fmt) |
TO_NUMBER(s, fmt) |
Same |
generate_series(a, b) |
TABLE(GENERATOR(ROWCOUNT => b-a+1)) |
|
array_agg(col) |
ARRAY_AGG(col) |
Same |
string_agg(col, delim) |
LISTAGG(col, delim) |
|
SUBSTR(s, pos, len) |
SUBSTR(s, pos, len) |
Same |
POSITION(s IN str) |
POSITION(s IN str) |
Same |
REGEXP_REPLACE(...) |
REGEXP_REPLACE(...) |
Same |
json_extract_path_text() |
JSON_EXTRACT_PATH_TEXT() |
Same |
::type cast |
::type cast |
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
- [] PostgreSQL-specific syntax converted (array expressions, CHAR padding, distribution keys)
- [] 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 |
| PostgreSQL / Greenplum / Netezza |
Array expressions (<> ALL, = ANY), CHAR padding differences, psql commands, distribution keys |
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
- Data Types Netezza Data Types
- Data Types Postgresql Data Types
- Ddls Create Materialized View Greenplum Create Materialized View
- Ddls Create Materialized View Postgresql Create Materialized View
- Ddls Create Table Greenplum Create Table
- Ddls Create Table Netezza Create Table
- Ddls Create Table Postgresql Create Table
- Ddls Postgresql Create View
- ETL BI Repointing Power BI Postgres Repointing
- Overview (README)
- Subqueries
- Built In Functions
- Expressions
- Interactive Terminal
- String Comparison
1---2name: dbt-migration-postgres3description: Convert PostgreSQL/Greenplum/Netezza DDL to dbt models compatible with Snowflake. This skill should be used when converting views, tables, or stored procedures from PostgreSQL, Greenplum, or Netezza to dbt code, generating schema.yml files with tests and documentation, or migrating PostgreSQL SQL to follow dbt best practices.4---5
6# PostgreSQL/Greenplum/Netezza to dbt Model Conversion
7
8## Purpose
9
10Transform PostgreSQL/Greenplum/Netezza DDL (views, tables, stored procedures) into
11production-quality dbt models compatible with Snowflake, maintaining the same business logic and
12data transformation steps while following dbt best practices.
13
14## When to Use This Skill
15
16Activate this skill when users ask about:
17
18- Converting PostgreSQL/Greenplum/Netezza views or tables to dbt models
19- Migrating PostgreSQL stored procedures to dbt
20- Translating PostgreSQL syntax to Snowflake
21- Generating schema.yml files with tests and documentation
22- Handling PostgreSQL-specific syntax conversions (array expressions, CHAR padding, psql commands)
23
24---
25
26## Task Description
27
28You are a database engineer working for a hospital system. You need to convert
29PostgreSQL/Greenplum/Netezza DDL to equivalent dbt code compatible with Snowflake, maintaining the
30same business logic and data transformation steps while following dbt best practices.
31
32## Input Requirements
33
34I will provide you the PostgreSQL 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: PostgreSQL/Greenplum/Netezza
68 Purpose: [brief description]
69 Conversion Notes: [key changes]
70 Description: [SQL logic description] */
71
72WITH source_data AS (
73 SELECT
74 -- SERIAL converted to INTEGER (use IDENTITY in table)
75 customer_id::INTEGER AS customer_id,
76 customer_name::VARCHAR(100) AS customer_name,
77 account_balance::NUMBER(18,2) AS account_balance,
78 -- TIMESTAMPTZ converted to TIMESTAMP_TZ
79 created_date::TIMESTAMP_TZ AS created_date
80 FROM {{ ref('upstream_model') }}
81),
82
83transformed_data AS (
84 SELECT
85 customer_id,
86 UPPER(customer_name)::VARCHAR(100) AS customer_name_upper,
87 account_balance,
88 created_date,
89 CURRENT_TIMESTAMP()::TIMESTAMP_NTZ AS loaded_at
90 FROM source_data
91)
92
93SELECT
94 customer_id,
95 customer_name_upper,
96 account_balance,
97 created_date,
98 loaded_at
99FROM transformed_data
100```
101
102```yaml
103## models/[domain]/[target_schema_name]/_models.yml
104version: 2
105
106models:
107 - name: model_name
108 description: "Table description; converted from PostgreSQL [Original object name]"
109 columns:
110 - name: customer_id
111 description: "Primary key - unique customer identifier"
112 tests:
113 - unique
114 - not_null
115 - name: customer_name_upper
116 description: "Customer name in uppercase"
117 - name: account_balance
118 description: "Current account balance; Foreign key to OTHER_TABLE"
119 tests:
120 - relationships:
121 to: ref('OTHER_TABLE')
122 field: OTHER_TABLE_KEY
123 - name: created_date
124 description: "Date the customer record was created"
125 - name: loaded_at
126 description: "Timestamp when the record was loaded by dbt"
127```
128
129```yaml
130## dbt_project.yml (excerpt)
131models:
132 my_project:
133 +materialized: view
134 domain_name:
135 +schema: target_schema_name
136```
137
138### Specific Translation Rules
139
140#### dbt Specific Requirements
141
142- If the source is a view, use a view materialization in dbt
143- Include appropriate dbt model configuration (materialization type)
144- Add documentation blocks for a schema.yml
145- Add descriptions for tables and columns
146- Include relevant tests
147- Define primary keys and relationships
148- Assume that upstream objects are models
149- Comprehensively provide all the columns in the output
150- Break complex procedures into multiple models if needed
151- Implement appropriate incremental strategies for large tables
152- Use Snowflake SQL functions rather than macros whenever possible
153- **Always cast columns with explicit precision/scale** using `::TYPE` syntax (e.g.,
154 `column_name::VARCHAR(100)`, `amount::NUMBER(18,2)`) to ensure output matches expected data types
155- **Always provide explicit column aliases** for clarity and documentation
156
157#### Performance Optimization
158
159- Suggest clustering keys if needed
160- Recommend materialization strategy (view vs table)
161- Identify potential performance improvements
162
163#### PostgreSQL to Snowflake Syntax Conversion
164
165- Convert array expressions (<> ALL, = ANY) to Snowflake equivalents
166- Handle CHAR padding differences
167- Replace psql commands with SnowSQL equivalents
168- Convert distribution keys (Greenplum) to clustering keys
169- Handle string comparison behavior differences
170- Convert PL/pgSQL to Snowflake Scripting
171- Replace PostgreSQL-specific operators
172- Handle SERIAL/BIGSERIAL with IDENTITY
173
174#### Key Data Type Mappings
175
176| PostgreSQL | Snowflake | Notes |
177| ----------------------- | ---------------------- | ----------------------- |
178| INTEGER/INT/INT4 | INTEGER | |
179| BIGINT/INT8 | BIGINT | |
180| SMALLINT/INT2 | SMALLINT | |
181| SERIAL/BIGSERIAL | IDENTITY | Use AUTOINCREMENT |
182| NUMERIC/DECIMAL | NUMERIC | |
183| REAL/FLOAT4 | FLOAT | |
184| DOUBLE PRECISION/FLOAT8 | FLOAT | |
185| BOOLEAN/BOOL | BOOLEAN | |
186| CHAR/VARCHAR/TEXT | Same | |
187| BYTEA | BINARY | |
188| DATE | DATE | |
189| TIME/TIMETZ | TIME | Time zone not supported |
190| TIMESTAMP/TIMESTAMPTZ | TIMESTAMP/TIMESTAMP_TZ | |
191| INTERVAL | VARCHAR | |
192| JSON/JSONB | VARIANT | |
193| ARRAY | ARRAY | |
194| UUID | VARCHAR | |
195
196#### Key Syntax Conversions
197
198```sql
199-- SERIAL -> AUTOINCREMENT
200id SERIAL PRIMARY KEY -> id INT AUTOINCREMENT PRIMARY KEY
201
202-- Array expressions
203col <> ALL(ARRAY[1,2,3]) -> NOT ARRAY_CONTAINS(col, ARRAY_CONSTRUCT(1,2,3))
204col = ANY(ARRAY[1,2,3]) -> ARRAY_CONTAINS(col, ARRAY_CONSTRUCT(1,2,3))
205
206-- psql commands -> SnowSQL
207\d table -> DESCRIBE TABLE table
208\dt -> SHOW TABLES
209
210-- generate_series -> TABLE(GENERATOR())
211generate_series(1, 10) -> TABLE(GENERATOR(ROWCOUNT => 10))
212
213-- NOW() -> CURRENT_TIMESTAMP
214NOW() -> CURRENT_TIMESTAMP()
215```
216
217#### Common Function Mappings
218
219| PostgreSQL | Snowflake | Notes |
220| -------------------------- | ------------------------------------- | --------------- |
221| `COALESCE(...)` | `COALESCE(...)` | Same |
222| `NULLIF(a, b)` | `NULLIF(a, b)` | Same |
223| `NOW()` | `CURRENT_TIMESTAMP()` | |
224| `CURRENT_DATE` | `CURRENT_DATE()` | Add parentheses |
225| `CURRENT_TIMESTAMP` | `CURRENT_TIMESTAMP()` | Add parentheses |
226| `DATE_TRUNC(unit, d)` | `DATE_TRUNC(unit, d)` | Same |
227| `EXTRACT(part FROM d)` | `EXTRACT(part FROM d)` | Same |
228| `TO_CHAR(d, fmt)` | `TO_CHAR(d, fmt)` | Same |
229| `TO_DATE(s, fmt)` | `TO_DATE(s, fmt)` | Same |
230| `TO_NUMBER(s, fmt)` | `TO_NUMBER(s, fmt)` | Same |
231| `generate_series(a, b)` | `TABLE(GENERATOR(ROWCOUNT => b-a+1))` | |
232| `array_agg(col)` | `ARRAY_AGG(col)` | Same |
233| `string_agg(col, delim)` | `LISTAGG(col, delim)` | |
234| `SUBSTR(s, pos, len)` | `SUBSTR(s, pos, len)` | Same |
235| `POSITION(s IN str)` | `POSITION(s IN str)` | Same |
236| `REGEXP_REPLACE(...)` | `REGEXP_REPLACE(...)` | Same |
237| `json_extract_path_text()` | `JSON_EXTRACT_PATH_TEXT()` | Same |
238| `::type` cast | `::type` cast | Same |
239
240#### Dependencies
241
242- List any upstream dependencies
243- Suggest model organization in dbt project
244
245---
246
247## Validation Checklist
248
249- [] Every DDL statement has been accounted for in the dbt models
250- [] SQL in models is compatible with Snowflake
251- [] PostgreSQL-specific syntax converted (array expressions, CHAR padding, distribution keys)
252- [] All business logic preserved
253- [] All columns included in output
254- [] Data types correctly mapped
255- [] Functions translated to Snowflake equivalents
256- [] Materialization strategy selected
257- [] Tests added
258- [] SQL logic description complete
259- [] Table descriptions added
260- [] Column descriptions added
261- [] Dependencies correctly mapped
262- [] Incremental logic (if applicable) verified
263- [] Inline comments added for converted syntax
264
265---
266
267## Related Skills
268
269- $dbt-migration - For the complete migration workflow (discovery, planning, placeholder models,
270 testing, deployment)
271- $dbt-modeling - For CTE patterns and SQL structure guidance
272- $dbt-testing - For implementing comprehensive dbt tests
273- $dbt-architecture - For project organization and folder structure
274- $dbt-materializations - For choosing materialization strategies (view, table, incremental,
275 snapshots)
276- $dbt-performance - For clustering keys, warehouse sizing, and query optimization
277- $dbt-commands - For running dbt commands and model selection syntax
278- $dbt-core - For dbt installation, configuration, and package management
279- $snowflake-cli - For executing SQL and managing Snowflake objects
280
281---
282
283## Supported Source Database
284
285| Database | Key Considerations |
286| ------------------------------------ | --------------------------------------------------------------------------------------------- |
287| **PostgreSQL / Greenplum / Netezza** | Array expressions (<> ALL, = ANY), CHAR padding differences, psql commands, distribution keys |
288
289## Translation References
290
291Detailed syntax translation guides are available in the `translation-references/` folder.
292
293> **Copyright Notice:** The translation reference documentation in this repository is derived from
294> [Snowflake SnowConvert Documentation](https://docs.snowflake.com/en/migrations/snowconvert-docs)
295> and is © Copyright Snowflake Inc. All rights reserved. Used for reference purposes only.
296
297### Reference Index
298
299- [Data Types Netezza Data Types](translation-references/postgres-data-types-netezza-data-types.md)
300- [Data Types Postgresql Data Types](translation-references/postgres-data-types-postgresql-data-types.md)
301- [Ddls Create Materialized View Greenplum Create Materialized View](translation-references/postgres-ddls-create-materialized-view-greenplum-create-materialized-view.md)
302- [Ddls Create Materialized View Postgresql Create Materialized View](translation-references/postgres-ddls-create-materialized-view-postgresql-create-materialized-view.md)
303- [Ddls Create Table Greenplum Create Table](translation-references/postgres-ddls-create-table-greenplum-create-table.md)
304- [Ddls Create Table Netezza Create Table](translation-references/postgres-ddls-create-table-netezza-create-table.md)
305- [Ddls Create Table Postgresql Create Table](translation-references/postgres-ddls-create-table-postgresql-create-table.md)
306- [Ddls Postgresql Create View](translation-references/postgres-ddls-postgresql-create-view.md)
307- [ETL BI Repointing Power BI Postgres Repointing](translation-references/postgres-etl-bi-repointing-power-bi-postgres-repointing.md)
308- [Overview (README)](translation-references/postgres-readme.md)
309- [Subqueries](translation-references/postgres-subqueries.md)
310- [Built In Functions](translation-references/postgresql-built-in-functions.md)
311- [Expressions](translation-references/postgresql-expressions.md)
312- [Interactive Terminal](translation-references/postgresql-interactive-terminal.md)
313- [String Comparison](translation-references/postgresql-string-comparison.md)