Openflow Connector for PostgreSQL: Iceberg table destinations¶
The Openflow Connector for PostgreSQL supports writing to Snowflake-managed Apache Apache Iceberg™ tables
as an opt-in destination format. Iceberg v2 and v3 are both supported. Setting Table Storage Format = ICEBERG
and choosing an Iceberg Version are the only connector-level changes required. The external volume,
catalog, and serialization policy are inherited from the Snowflake destination database defaults.
The Iceberg specification version is set via the Iceberg Version connector parameter, which
defaults to 3 for both Gen2 (Openflow UI wizard) and Gen1 (parameter context) connectors.
Storage can be either Snowflake storage for Apache Apache Iceberg™ tables
(EXTERNAL_VOLUME = 'SNOWFLAKE_MANAGED') or an external volume in your cloud storage. When you use
Snowflake storage, no external cloud storage or IAM grants are required.
Existing connectors using standard tables aren’t affected.
Prerequisites¶
- Openflow runtime: An existing runtime to host the connector.
- PostgreSQL source configured for CDC: Logical replication enabled (
wal_level = logical), a publication created, and a user with replication privileges. For details, see Set up the Openflow Connector for PostgreSQL. - External volume in your cloud storage: An external volume configured for Iceberg storage,
with USAGE granted to the connector’s Snowflake role. See
CREATE EXTERNAL VOLUME. Not required when using
Snowflake storage (
EXTERNAL_VOLUME = 'SNOWFLAKE_MANAGED'). - Snowflake destination database: An existing database configured with Iceberg parameters (next section).
Step 1: Configure the Snowflake destination database¶
Set the Iceberg defaults on the destination database. The connector reads these defaults at runtime
for external volume and serialization policy. The Iceberg specification version is configured
per-connector via the Iceberg Version parameter (see Step 3), not solely via the database-level
ICEBERG_VERSION_DEFAULT.
Option A: Snowflake storage¶
When you use Snowflake storage, Snowflake stores and manages the Iceberg table files for you. No external cloud storage or IAM grants are required.
To configure an existing database:
Option B: External volume in your cloud storage¶
If you need to keep table files in your own cloud storage, configure the database with your external volume:
To configure an existing database:
| Parameter | Required | Notes |
|---|---|---|
| EXTERNAL_VOLUME | Yes | The external volume for Iceberg file storage. |
| ICEBERG_VERSION_DEFAULT | No |
|
| STORAGE_SERIALIZATION_POLICY | Yes |
|
Note
CATALOG = 'SNOWFLAKE' is set automatically by the connector on each CREATE ICEBERG TABLE
statement. Don’t set it at the database level.
The base location for each table is auto-derived using the
flat layout:
STORAGE_BASE_URL/database/schema/table_name.randomId/[data | metadata]/.
No user configuration is needed.
If using an external volume in your cloud storage (Option B), grant the connector’s Snowflake role USAGE on the external volume:
This step is not required for Snowflake storage.
Step 2: Set Table Storage Format in the connector’s parameter context¶
Set the Table Storage Format parameter to ICEBERG in the connector’s destination parameter context.
The default is STANDARD.
For the full connector creation and configuration workflow, see Set up the Openflow Connector for PostgreSQL.
Step 3: Set the Iceberg version¶
Set the Iceberg Version connector parameter to 2 or 3. This controls the Iceberg specification
version used for type mapping (for example, JSON/JSONB maps to variant on v3 vs string on v2)
and the ICEBERG_VERSION=<n> clause in CREATE ICEBERG TABLE DDL.
- Gen2 (Openflow UI wizard): Iceberg Version is a required field when Table Storage Format =
ICEBERG, defaulting to3. This setting is immutable after the connector configuration is first applied. - Gen1 (parameter context): The Iceberg Version parameter defaults to
3. Review and change to2if needed before starting the connector. Do not change this value after ingestion begins.
Step 4: Start and verify¶
Start the connector as usual. After the initial snapshot completes, verify the destination tables are Iceberg:
Known limitations¶
- Tri-Secret Secure accounts and Snowflake storage: Accounts with Tri-Secret Secure (TSS) enabled may be unable to create new Snowflake-managed Iceberg tables that use Snowflake storage for Apache Apache Iceberg™ tables. For details, see Encryption.
- Incompatible type changes on the source cause table failure: Only same-family type widening
is allowed on Iceberg tables (for example,
inttolong,floattodouble, ordecimal(P,S)todecimal(P',S)with wider precision). Cross-family changes such asinttodecimal,longtostring, orinttobooleanare not allowed. If a source column’s type changes to an incompatible Iceberg type, the table is marked as failed and requires a rebootstrap. - TIMETZ offset not preserved: Iceberg
timestamptzstores only the UTC instant. PostgreSQL TIMETZ values lose the original timezone offset when written to Iceberg tables. - Do not change Table Storage Format or Iceberg Version after the connector starts: The connector’s Table Storage Format and Iceberg Version parameter should not be modified after ingestion begins. Gen2 connectors enforce this by making Iceberg Version immutable after first apply. Mixing settings across destination tables is not supported. To switch, follow the steps in Switching table storage format or Iceberg version.
Type mapping reference¶
The following table shows how PostgreSQL types map to Snowflake standard and Iceberg destination types:
| PostgreSQL type | Snowflake (Standard) | Iceberg v3 | Iceberg v2 |
|---|---|---|---|
| SMALLINT / INTEGER | INT | int | int |
| BIGINT | INT | long | long |
| REAL | FLOAT | double | double |
| DOUBLE PRECISION | FLOAT | double | double |
| NUMERIC(P,S) | NUMBER(P,S) | decimal(P,S) | decimal(P,S) |
| BOOLEAN | BOOLEAN | boolean | boolean |
| DATE | DATE | date | date |
| TIME | TIME | time | time |
| TIMESTAMP | TIMESTAMP_NTZ | timestamp | timestamp |
| TIMESTAMPTZ | TIMESTAMP_LTZ | timestamptz | timestamptz |
| TIMETZ | TIMESTAMP_TZ | timestamptz | timestamptz |
| TEXT / VARCHAR / CHAR | TEXT | string | string |
| BYTEA | BINARY | binary | binary |
| JSON / JSONB | VARIANT | variant | string |
| UUID | TEXT | string | string |
Source types not listed in the table are mapped to TEXT on standard tables and string on Iceberg
tables.
Switching table storage format or Iceberg version¶
Switching between Standard and Iceberg, or between Iceberg v2 and v3, requires recreating the connector. Follow these steps:
- Stop the connector.
- Delete the process group in Openflow.
- Manually clean up the destination database (drop the replicated schemas/tables, or use a new database).
- Reimport the connector with the new Table Storage Format and select the target Iceberg Version when configuring the connector.
This ensures all connector state is correctly cleaned up within Openflow. The new connector performs a fresh snapshot into the destination.
Upgrading an existing connector to use Iceberg Version pinning¶
Gen2 connector version 2026.7.21 and Gen1 connector version 0.60.0 introduce the
Iceberg Version parameter. If you are upgrading from an earlier connector version (for example,
Gen1 0.56.0 to 0.60.0 or later), a new Iceberg Version field appears that you must configure
to match your existing destination tables.
- Stop the connector.
- Upgrade the runtime
to version
2026.7.21or later. - Upgrade the connector
in place (Gen2: to version
2026.7.21or later; Gen1: to version0.60.0or later). - Set the Iceberg Version parameter to match your existing destination tables:
- Gen2 (Openflow UI wizard): After upgrading, open the connector configuration wizard.
The Destination details step now includes a required Iceberg Version field, defaulting
to
3. If your existing destination tables are Iceberg v2, change it to2before applying. This choice is locked after first apply and cannot be changed later. - Gen1 (parameter context): The Iceberg Version parameter defaults to
3after the flow upgrade. If your existing destination tables are Iceberg v2, change it to2before starting the connector.
- Gen2 (Openflow UI wizard): After upgrading, open the connector configuration wizard.
The Destination details step now includes a required Iceberg Version field, defaulting
to
- Start the connector.
Caution
Selecting an Iceberg Version that doesn’t match your existing destination tables can cause type-mapping errors or DDL failures. Always verify the version of your existing tables before choosing a value.