Convert Google BigQuery DDL to dbt models compatible with Snowflake. This skill should be used when converting views, tables, or stored procedures from BigQuery to dbt code, generating schema.yml files with tests and documentation, or migrating BigQuery SQL to follow dbt best practices.
Transform Google BigQuery 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.
Activate this skill when users ask about:
Do NOT begin manual conversion of tables or views. BigQuery has partial SnowConvert AI support (tables and views only — procedures and functions are NOT supported). Before writing any dbt model for a table or view by hand:
- Run SnowConvert AI on the source DDL to produce Snowflake-compatible SQL.
- Use the
$dbt-migration-snowflakeskill to convert the SCAI output to dbt models.- Only fall back to this skill's manual translation rules for objects SCAI could not convert (check the conversion report for EWIs) or for procedures/functions (which require manual conversion).
See the
$dbt-migrationskill for download links and full workflow.
Preserve original object names. The dbt model filename and model name MUST match the original source object name (lowercased, without project/dataset prefix). For example,
my_project.my_dataset.patient_visitsbecomespatient_visits.sql. Do not rename objects during migration unless explicitly requested by the user.
You are a database engineer working for a hospital system. You need to convert BigQuery DDL to equivalent dbt code compatible with Snowflake, maintaining the same business logic and data transformation steps while following dbt best practices.
I will provide you the BigQuery 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: [project].[dataset].[object_name]
Source Platform: BigQuery
Purpose: [brief description]
Conversion Notes: [key changes]
Description: [SQL logic description] */
WITH source_data AS (
SELECT
-- INT64 converted to INTEGER
customer_id::INTEGER AS customer_id,
-- STRING converted to VARCHAR
customer_name::VARCHAR(100) AS customer_name,
-- NUMERIC converted to NUMBER
account_balance::NUMBER(18,2) AS account_balance,
-- TIMESTAMP converted to TIMESTAMP_TZ (BigQuery stores UTC)
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 BigQuery [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 types| BigQuery | Snowflake | Notes | | -------------------------- | ------------- | ----------------------------- | | INT64/INT/INTEGER/BIGINT | INT | Alias for NUMBER(38,0) | | SMALLINT/TINYINT/BYTEINT | Same | | | NUMERIC/DECIMAL/BIGNUMERIC | NUMERIC | BIGNUMERIC may lose precision | | FLOAT64 | FLOAT | | | BOOL/BOOLEAN | BOOLEAN | | | STRING | VARCHAR | | | BYTES | BINARY | | | DATE | DATE | | | TIME | TIME | | | DATETIME | TIMESTAMP_NTZ | | | TIMESTAMP | TIMESTAMP_TZ | BigQuery stores in UTC | | ARRAY<T> | ARRAY | | | STRUCT | VARIANT | Use OBJECT_CONSTRUCT | | JSON | VARIANT | Use PARSE_JSON | | GEOGRAPHY | GEOGRAPHY | | | INTERVAL | VARCHAR | |
-- Backtick identifiers → Double quotes
`project.dataset.table` → "project"."dataset"."table"
-- UNNEST → LATERAL FLATTEN
SELECT * FROM table, UNNEST(array_col) AS elem →
SELECT * FROM table, LATERAL FLATTEN(input => array_col) AS f
-- STRUCT → OBJECT_CONSTRUCT
STRUCT(1 AS a, 'x' AS b) → OBJECT_CONSTRUCT('a', 1, 'b', 'x')
-- ARRAY access
array_col[OFFSET(0)] → array_col[0]
array_col[ORDINAL(1)] → array_col[0]
-- SAFE_* functions → TRY_* or :: with TRY_
SAFE_CAST(x AS INT64) → TRY_TO_NUMBER(x)::INTEGER
SAFE_CAST(x AS STRING) → x::VARCHAR -- regular cast when safe
SAFE_DIVIDE(a, b) → a / NULLIF(b, 0) -- returns NULL on divide by zero
-- IS TRUE/IS FALSE
WHERE col IS TRUE → WHERE col = TRUE
-- ARRAY_AGG
ARRAY_AGG(col) → ARRAY_AGG(col)
-- JSON functions
JSON_VALUE(col, '$.key') → col:key::STRING
| BigQuery | Snowflake | Notes |
| -------------------------- | ------------------------------------ | ------------------- |
| IF(cond, a, b) | IFF(cond, a, b) | |
| IFNULL(a, b) | IFNULL(a, b) | Same |
| COUNTIF(cond) | COUNT_IF(cond) | |
| LOGICAL_AND(col) | BOOLAND_AGG(col) | |
| LOGICAL_OR(col) | BOOLOR_AGG(col) | |
| SAFE_CAST(x AS type) | TRY_CAST(x AS type) | |
| ARRAY_CONCAT(a, b) | ARRAY_CAT(a, b) | |
| ARRAY_LENGTH(arr) | ARRAY_SIZE(arr) | |
| FORMAT_DATE(fmt, d) | TO_CHAR(d, fmt) | Format codes differ |
| CURRENT_DATETIME() | CURRENT_TIMESTAMP()::TIMESTAMP_NTZ | |
| JSON_VALUE(col, '$.key') | col:key::STRING | Path syntax differs |
| JSON_EXTRACT_SCALAR(...) | JSON_EXTRACT_PATH_TEXT(...) | |
| STARTS_WITH(str, prefix) | STARTSWITH(str, prefix) | |
| ENDS_WITH(str, suffix) | ENDSWITH(str, suffix) | |
| REGEXP_CONTAINS(val, re) | REGEXP_INSTR(val, re) > 0 | |
| TIMESTAMP_MILLIS(ms) | TO_TIMESTAMP(ms / 1000) | |
| UNIX_MILLIS(ts) | DATE_PART('epoch_millisecond', ts) | |
| ST_GEOGFROMTEXT(wkt) | ST_GEOGRAPHYFROMWKT(wkt) | |
| ST_GEOGPOINT(lon, lat) | ST_POINT(lon, lat) | |
| Database | Key Considerations | | ------------------- | --------------------------------------------------------------------------------------------- | | Google BigQuery | UNNEST, STRUCT/ARRAY types, backtick identifiers, IS TRUE/FALSE operators, SAFE_* functions |
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.
npx skills add sfc-gh-dflippo/dbt-migration-bigquery下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer