DuckDB
Supermetal replicates to DuckDB over the Quack protocol, DuckDB's native binary protocol on HTTP.
Prerequisites
- A DuckDB instance with the Quack extension serving over HTTP.
- Network connectivity from Supermetal to the Quack endpoint (default port 9494).
Setup
Start a Quack server
Install the Quack extension and start serving.
INSTALL quack;
LOAD quack;
CALL quack_serve('quack:0.0.0.0:9494', allow_other_hostname => true);This prints the listen URI, HTTP URL, and a generated authentication token. Save the token for the next step.
Configure the connection
| Field | Description |
|---|---|
| URL | HTTP URL of the Quack endpoint (e.g., http://localhost:9494) |
| Token | Authentication token returned by quack_serve |
| SSL Verify | Verify the server's TLS certificate. Disable if the certificate is not issued by a trusted CA. |
Target database and schema
| Field | Default | Description |
|---|---|---|
| Target Database | (required) | Database to write into. Must be attached on the DuckDB server before syncing. Can be any attached database, including DuckLake catalogs. Verify with SHOW DATABASES. |
| Target Schema | Optional. When set, all source tables land in this schema regardless of their source schema. Otherwise, each table keeps its source schema. Created if it does not exist. |
Primary Keys
Opt in. Supermetal deduplicates using MERGE without primary key constraints on the table. Enabling primary keys adds the constraint, enforcing uniqueness at the database level.
On DuckDB versions before 1.4, primary key constraints are required for dedup.
Multi table transactions
Opt in. When enabled, each CDC batch wraps in a transaction, preserving source transaction boundaries across tables.
DuckLake
DuckLake databases work as any other attached target database. Set the target database to the name of your attached DuckLake catalog and Supermetal writes to it directly. No additional setup required.
Data Types Mapping
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
Int8 | TINYINT | |
Int16 | SMALLINT | |
Int32 | INTEGER | |
Int64 | BIGINT | |
UInt8 | UTINYINT | |
UInt16 | USMALLINT | |
UInt32 | UINTEGER | |
UInt64 | UBIGINT | |
Float16 | FLOAT | |
Float32 | FLOAT | |
Float64 | DOUBLE | |
Decimal128(p,s) | DECIMAL(p,s) | Falls back to VARCHAR when precision exceeds 38 |
Decimal256(p,s) | DECIMAL(p,s) | Falls back to VARCHAR when precision exceeds 38 |
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
Boolean | BOOLEAN |
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
Date32, Date64 | DATE | |
Time32, Time64 | TIME | |
Timestamp(s, None) | TIMESTAMP_S | |
Timestamp(ms, None) | TIMESTAMP_MS | |
Timestamp(us, None) | TIMESTAMP | Microsecond precision, DuckDB's default |
Timestamp(ns, None) | TIMESTAMP_NS | |
Timestamp(ns, "UTC") | TIMESTAMP_NS | |
Timestamp(*, "UTC") | TIMESTAMP | UTC timestamps except nanosecond |
Timestamp(*, tz) | TIMESTAMPTZ | Time zones other than UTC |
Interval | INTERVAL | |
Duration | VARCHAR |
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
Utf8, LargeUtf8 | VARCHAR |
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
Binary, LargeBinary, FixedSizeBinary | BLOB |
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
Utf8 with arrow.json extension | VARIANT | DuckDB 1.5+. Falls back to JSON on older versions. |
Struct | STRUCT(...) | Field names and types preserved |
Map | MAP(K, V) |
| Arrow Type | DuckDB Type | Notes |
|---|---|---|
List<T>, LargeList<T>, FixedSizeList<T> | T[] |
Nullability
Nullable source columns are nullable on the target. All columns except primary keys are nullable by default to handle CDC edge cases. Enable preserve_source_nullability to carry over NOT NULL constraints from the source schema.
Changelog
Last updated on