The Snowflake sink lands the full append-only CDC history in a Snowflake database. Rows are buffered to a local Parquet file, put to a named internal stage, and loaded with COPY INTO … MATCH_BY_COLUMN_NAME. There is no merge or upsert: every change is a new row, and current state is resolved downstream.
Prerequisites
- A Snowflake account, identified as
<org>-<account_locator>. - A user, authenticated with a key pair (preferred) or a password.
- A compute warehouse the role can use and resume. The connection test resumes a suspended warehouse.
- The target database must already exist — Fabric creates schemas, stages, and tables inside it, never the database.
- Outbound HTTPS to the account host, and a role with the privileges the writer needs:
GRANT USAGE, OPERATE ON WAREHOUSE <warehouse> TO ROLE <role>;
GRANT USAGE ON DATABASE <database> TO ROLE <role>;
GRANT CREATE SCHEMA ON DATABASE <database> TO ROLE <role>;
GRANT USAGE, CREATE STAGE, CREATE TABLE
ON SCHEMA <database>.<schema> TO ROLE <role>;
GRANT INSERT, SELECT ON ALL TABLES IN SCHEMA <database>.<schema>
TO ROLE <role>;
GRANT INSERT, SELECT ON FUTURE TABLES IN SCHEMA <database>.<schema>
TO ROLE <role>;Connection fields
| Field | Required | Default | Notes |
|---|---|---|---|
| Name | Yes | — | Destination label. |
| Account | Yes | — | <org>-<account_locator>. |
| Username | Yes | — | Login name of the service user. |
| Authentication | Yes | Key pair | Key pair (preferred) or password. |
| Private key | Yes when using key pair | — | A PKCS#8 PEM key. Write-only; blank on edit keeps the stored key. |
| Key passphrase | No | — | Only for an encrypted private key. |
| Password | Yes when using password | — | Write-only; blank on edit keeps the stored password. |
| Warehouse | Yes | — | Compute warehouse used for loads and DDL. |
| Database | Yes | — | Must already exist. |
| Role | No | user's default role |
How tables land
The three-level namespace maps as <database>.<namespace>.<table>: the destination's database, the sync's namespace as the schema (raw by default), and the sync's table name. Fabric creates the schema, the FABRIC_STAGE stage, and the table on first write; later columns are added additively.
- A commit happens only after
COPY INTOconfirms every row loaded. The staged filename is a deterministic digest of the batch, so a replayed batch is deduplicated by Snowflake's load history rather than doubling the data. - The commit floor is raised to five minutes. Small, frequent loads cause micro-partition bloat and credit burn, so the longer interval is intentional — Snowflake is the one sink that overrides the configured commit interval upward.
- A high-water mark of 200,000 buffered rows forces a commit before the interval elapses.
Gotchas
Watch out
- Append-only, no merge: resolve current state with a window function over
__source_ts_mspartitioned by the identifier columns. - A bad row aborts the whole load — errors are not skipped. After repeated failures the batch is quarantined and the cursor advances, so one broken table cannot wedge the source.
- JSON lands as
VARCHAR, notVARIANT. Add aPARSE_JSONview if you need a real variant. - Identifiers are case-preserving (double-quoted), so an unquoted query folds to uppercase and sees nothing.