In Iceberg schreiben
Die iceberg-Erweiterung unterstützt das Schreiben in Iceberg-Tabellen, die von einem Iceberg REST Catalog verwaltet werden. Alle Schreiboperationen laufen über den angehängten Katalog und werden als neue Iceberg-Snapshots festgeschrieben.
Das Schreiben erfordert einen angehängten Katalog. Die pfadbasierte
iceberg_scan-Schnittstelle, die im Überblick beschrieben ist, ist schreibgeschützt. Um zu schreiben, hängen Sie zuerst einen Iceberg-REST-Katalog an.
Die folgenden Beispiele setzen voraus, dass ein Katalog als my_catalog angehängt wurde.
Schemas und Tabellen erstellen
Iceberg-Namespaces werden als Schemas bereitgestellt. Sie können Schemas und Tabellen mit Standard-SQL erstellen und löschen:
CREATE SCHEMA my_catalog.sales;USE my_catalog.sales;
CREATE TABLE my_catalog.sales.events ( id INTEGER, event_name VARCHAR, event_time TIMESTAMP);
-- Create a table from a queryCREATE TABLE my_catalog.sales.events_copy AS FROM my_catalog.sales.events;
DROP TABLE my_catalog.sales.events_copy;Partitionierung
Tabellen können mit der Klausel PARTITIONED BY unter Verwendung der Iceberg-Partition-Transforms partitioniert werden:
| Transform | Beschreibung |
|---|---|
⟨column⟩{:.language-sql .highlight} |
Identität – direkt nach dem Spaltenwert partitionieren. |
year(⟨column⟩){:.language-sql .highlight}, month(⟨column⟩){:.language-sql .highlight}, day(⟨column⟩){:.language-sql .highlight}, hour(⟨column⟩){:.language-sql .highlight} |
Nach einer Datums-/Zeitstempel-Komponente partitionieren. |
bucket(⟨n⟩, ⟨column⟩){:.language-sql .highlight} |
Die Spalte in n Buckets hashen. |
truncate(⟨n⟩, ⟨column⟩){:.language-sql .highlight} |
Den Spaltenwert auf die Breite n kürzen. |
CREATE TABLE my_catalog.sales.events ( id INTEGER, event_name VARCHAR, event_time TIMESTAMP)PARTITIONED BY (day(event_time), bucket(16, id));Die Partitionsspezifikation einer bestehenden Tabelle kann mit ALTER TABLE ... SET PARTITIONED BY geändert werden:
ALTER TABLE my_catalog.sales.events SET PARTITIONED BY (month(event_time));Die Tabelleneigenschaften
write.target-file-size-bytesundwrite.parquet.row-group-size-byteswerden für partitionierte Tabellen nicht berücksichtigt und lösen einen Fehler aus. Setzen Sieignore_target_file_size_for_partitioned_tablesoderignore_row_group_size_for_partitioned_tablesauftrue, um sie stattdessen zu ignorieren.
Tabelleneigenschaften
Iceberg-Tabelleneigenschaften können beim Erstellen mit einer WITH-Klausel gesetzt werden. Die Schlüssel format-version und location werden gesondert erkannt; alle anderen Schlüssel-Wert-Paare werden als Tabelleneigenschaften gespeichert:
CREATE TABLE my_catalog.sales.events (a INTEGER)WITH ( 'format-version' = '2', -- Iceberg format version (2 or 3) 'location' = 's3://my-bucket/events', -- base location for the table's data 'my.custom.property' = 'value');Bestehende Eigenschaften können mit den Property-Funktionen eingesehen und geändert werden:
-- View propertiesSELECT * FROM iceberg_table_properties(my_catalog.sales.events);
-- Set propertiesCALL set_iceberg_table_properties( my_catalog.sales.events, MAP {'write.update.mode': 'merge-on-read', 'write.delete.mode': 'merge-on-read'});
-- Remove propertiesCALL remove_iceberg_table_properties(my_catalog.sales.events, ['my.custom.property']);Siehe die Referenz zu Funktionen und Einstellungen für die entsprechenden Schema- (Namespace-) Property-Funktionen.
Daten einfügen
INSERT INTO my_catalog.sales.eventsVALUES (1, 'click', TIMESTAMP '2026-06-01 10:00:00');
-- Insert the result of a queryINSERT INTO my_catalog.sales.events SELECT * FROM source_table;
-- Match columns by name rather than positionINSERT INTO my_catalog.sales.events BY NAME SELECT event_time, id, event_name FROM source_table;Aktualisieren und Löschen
UPDATE my_catalog.sales.events SET event_name = 'view' WHERE id = 1;
DELETE FROM my_catalog.sales.events WHERE event_time < TIMESTAMP '2026-01-01';UPDATE und DELETE werden sowohl auf partitionierten als auch auf nicht partitionierten Tabellen unterstützt. Sie verwenden merge-on-read-Semantik und schreiben positional-delete-Dateien; siehe Einschränkungen.
Daten zusammenführen
MERGE INTO führt ein Upsert gegen eine Quellrelation aus. Der Join-Schlüssel wird mit einer zweiten USING-Klausel angegeben (siehe die MERGE INTO-Anweisung):
MERGE INTO my_catalog.sales.events AS targetUSING new_events AS source USING (id)WHEN MATCHED THEN UPDATE SET event_name = source.event_nameWHEN NOT MATCHED THEN INSERT VALUES (source.id, source.event_name, source.event_time);Schema weiterentwickeln
Die folgenden ALTER TABLE-Operationen werden unterstützt:
ALTER TABLE my_catalog.sales.events ADD COLUMN source VARCHAR DEFAULT 'web';ALTER TABLE my_catalog.sales.events DROP COLUMN source;ALTER TABLE my_catalog.sales.events RENAME COLUMN id TO event_id;ALTER TABLE my_catalog.sales.events ALTER COLUMN event_id TYPE BIGINT;ALTER TABLE my_catalog.sales.events RENAME TO event_log;ALTER TABLE my_catalog.sales.events ALTER COLUMN event_id SET DEFAULT 0;ALTER TABLE my_catalog.sales.events ALTER COLUMN event_id DROP DEFAULT;Kopieren zwischen DuckDB und Iceberg
Da der vollständige DDL- und DML-Satz unterstützt wird, kann COPY FROM DATABASE tiefe Kopien zwischen Iceberg- und DuckDB-Speicher in beide Richtungen durchführen:
COPY FROM DATABASE duckdb_db TO my_catalog;COPY FROM DATABASE my_catalog TO duckdb_db;Um einen Iceberg-Katalog nach DuckLake zu kopieren, siehe Interoperabilität mit DuckLake.
Einschränkungen
UPDATEundDELETEschreiben nur positional deletes; copy-on-write wird nicht unterstützt.UPDATEundDELETEunterstützen nur merge-on-read-Semantik. Wenn eine Tabellewrite.update.modeoderwrite.delete.modeauf etwas anderes alsmerge-on-readsetzt, schlägt die Operation fehl.- Die Tabelleneigenschaften
write.target-file-size-bytesundwrite.parquet.row-group-size-byteswerden für partitionierte Tabellen nicht berücksichtigt (siehe Partitionierung).