Avro-Erweiterung
Die Erweiterung avro ermöglicht DuckDB das Lesen von Apache-Avro-Dateien.
Die Erweiterung
avrowurde Ende 2024 als Community Extension veröffentlicht und ist Anfang 2025 zur Core Extension geworden.
Die Funktion read_avro
Die Erweiterung fügt eine einzelne DuckDB-Funktion hinzu: read_avro. Sie wird so verwendet:
FROM read_avro('⟨some_file⟩.avro');Diese Funktion stellt den Inhalt der Avro-Datei als DuckDB-Tabelle bereit. Anschließend können Sie beliebige SQL-Konstrukte nutzen, um diese Tabelle weiter zu transformieren.
Datei-I/O
Die Funktion read_avro ist in die Dateisystemabstraktion von DuckDB integriert. Sie können Avro-Dateien daher direkt von z. B. HTTP- oder S3-Quellen lesen. Beispiel:
FROM read_avro('https://blobs.duckdb.org/data/userdata1.avro');FROM read_avro('s3://⟨your-bucket⟩/⟨some_file⟩.avro');sollte „einfach“ funktionieren.
Sie können in einem Aufruf auch mehrere Dateien globben oder eine Liste von Dateien übergeben:
FROM read_avro('some_file_*.avro');FROM read_avro(['some_file_1.avro', 'some_file_2.avro']);Wenn die Dateinamen irgendwie wertvolle Informationen enthalten (was leider allzu häufig vorkommt), können Sie das Argument filename an read_avro übergeben:
FROM read_avro('some_file_*.avro', filename=true);Dann enthält die Ergebnismenge eine zusätzliche Spalte mit dem tatsächlichen Dateinamen der Avro-Datei.
Schema-Konvertierung
Diese Erweiterung übersetzt das Avro-Schema automatisch ins DuckDB-Schema. Alle Avro-Typen lassen sich übersetzen, außer rekursiven Typdefinitionen, die DuckDB nicht unterstützt.
Die Typzuordnung ist sehr geradlinig – mit Ausnahme der „einzigartigen“ Art, wie Avro NULL behandelt. Anders als andere Systeme behandelt Avro NULL nicht als möglichen Wert in einem Wertebereich wie z. B. INTEGER, sondern als Union des eigentlichen Typs mit einem speziellen NULL-Typ. In DuckDB hingegen kann jeder Wert NULL sein. DuckDB unterstützt zwar ebenfalls UNION-Typen, das wäre aber umständlich in der Handhabung.
Diese Erweiterung vereinfacht das Avro-Schema, wo das möglich ist: Eine Avro-Union aus einem beliebigen Typ und dem speziellen Null-Typ wird auf den Nicht-Null-Typ reduziert. Ein Avro-Record vom Union-Typ ["int","null"] wird so zu einem DuckDB-INTEGER, der gelegentlich NULL ist. Ebenso wird eine Avro-Union, die nur einen einzigen Typ enthält, in genau diesen Typ umgewandelt. Ein Avro-Record vom Union-Typ ["int"] wird ebenfalls zu einem DuckDB-INTEGER.
Die Erweiterung „flacht“ das Avro-Schema außerdem ab. Avro definiert Tabellen als Record-Felder auf der Wurzelebene, die DuckDB-STRUCT-Feldern entsprechen. Zur einfacheren Handhabung macht diese Erweiterung die Einträge eines einzelnen Top-Level-Records zu Top-Level-Spalten.
Implementierung
Intern verwendet diese Erweiterung die „offizielle“ Apache Avro C API, mit einigen kleinen Patches, damit Avro-Dateien aus dem Speicher gelesen werden können.
Einschränkungen und Ausblick
- Diese Erweiterung nutzt derzeit weder beim Lesen einer einzelnen (großen) Avro-Datei noch beim Lesen einer Dateiliste Parallelität. Unterstützung für Parallelität im zweiten Fall steht auf der Roadmap.
- Es gibt derzeit keine Unterstützung für Projektions- oder Filter-Pushdown; das ist ebenfalls für einen späteren Zeitpunkt geplant.
- Aufgrund von Problemen mit der Avro-Bibliotheksabhängigkeit (schon wieder) gibt es derzeit keine Unterstützung für die Wasm- oder Windows-MinGW-Builds von DuckDB. Wir wollen das irgendwann beheben.
- Wie oben erwähnt, kann DuckDB die rekursiven Typdefinitionen von Avro nicht ausdrücken; das wird sich wahrscheinlich nie ändern.
- Es gibt keine Möglichkeit, eine separate Avro-Schema-Datei anzugeben. Das wird sich wahrscheinlich nicht ändern; alle Avro-Dateien, die wir bisher gesehen haben, hatten das Schema eingebettet.
- Es gibt derzeit keine Unterstützung für das Flag
union_by_name, das andere Reader in DuckDB unterstützen. Das ist für die Zukunft geplant.