Sinks

Snowflake

Append-only history loaded through an internal stage — account, key-pair auth, and grants.

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

FieldRequiredDefaultNotes
NameYes—Destination label.
AccountYes—<org>-<account_locator>.
UsernameYes—Login name of the service user.
AuthenticationYesKey pairKey pair (preferred) or password.
Private keyYes when using key pair—A PKCS#8 PEM key. Write-only; blank on edit keeps the stored key.
Key passphraseNo—Only for an encrypted private key.
PasswordYes when using password—Write-only; blank on edit keeps the stored password.
WarehouseYes—Compute warehouse used for loads and DDL.
DatabaseYes—Must already exist.
RoleNouser'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 INTO confirms 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_ms partitioned 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, not VARIANT. Add a PARSE_JSON view if you need a real variant.
  • Identifiers are case-preserving (double-quoted), so an unquoted query folds to uppercase and sees nothing.