Frictionless-zu-Parquet-Typmapping¶
Beim CSV-Upload erzeugt das odi-staging-backend aus der validierten CSV-Datei
mehrere Repräsentationen, darunter eine Apache-Parquet-Datei. Damit die
Parquet-Spalten exakt den im Frictionless-Schema deklarierten Typen entsprechen
und nicht von der automatischen Typ-Inferenz von Apache Arrow abhängen, wird ein
explizites Mapping verwendet.
Wo wird das Mapping genutzt?¶
Die zentrale Typ-Map liegt im odi-staging-backend unter
src/upload/parquet/frictionless-to-parquet-type.map.ts.
Vor der Parquet-Erzeugung werden die CSV-Zeilen vom
CsvJsonService
in die passenden JavaScript-Werte konvertiert. Anschließend baut der
ParquetService
daraus ein Arrow-Schema mit expliziten Datentypen und schreibt es über
parquet-wasm als Parquet.
Logische und physische Parquet-Typen¶
Parquet unterscheidet zwischen zwei Ebenen:
- Physischer Typ: Beschreibt, wie die Rohbytes in der Datei abgelegt werden
(z. B.
BYTE_ARRAY,INT32,INT64,DOUBLE). Er ist werkzeugunabhängig und Teil des Parquet-Formats. - Logischer Typ: Gibt die semantische Bedeutung der physischen Daten an
(z. B.
UTF8,DATE,TIMESTAMP). Viele Werkzeuge zeigen den logischen Typ an, verwenden aber eigene Namen dafür.
Darum kann ein und dieselbe Spalte je nach Betrachter unterschiedlich
beschriftet sein: Parquet selbst und Apache Arrow sprechen von UTF8,
während Datenbank-Werkzeuge und einige Parquet-Viewer den logischen Typ
häufig als VARCHAR oder STRING anzeigen. UTF8, VARCHAR und STRING
bedeuten hier dasselbe: eine variable Zeichenkette.
Mapping-Tabelle¶
| Frictionless-Typ | Parquet-Typ (logisch) | Parquet-Typ (physisch) | Beschreibung |
|---|---|---|---|
string |
UTF8 (VARCHAR) |
BYTE_ARRAY |
Beliebiger Text. |
number |
DOUBLE |
DOUBLE |
Gleitkommazahlen (IEEE 754 doppelte Genauigkeit). |
integer |
INT64 (BIGINT) |
INT64 |
Ganze Zahlen mit Vorzeichen (64 Bit). |
boolean |
BOOLEAN |
BOOLEAN |
Wahrheitswerte. |
date |
DATE |
INT32 |
Kalenderdatum ohne Uhrzeit. |
datetime |
TIMESTAMP(MILLIS, UTC) (TIMESTAMP) |
INT64 |
Zeitstempel mit Millisekundengenauigkeit. |
time |
TIME(MILLIS) (TIME) |
INT32 |
Tageszeit in Millisekunden seit Mitternacht. |
year |
INT64 (BIGINT) |
INT64 |
Jahreszahl als Ganzzahl. |
yearmonth |
UTF8 (VARCHAR) |
BYTE_ARRAY |
Jahr-Monat-Kombination, als ISO-Text belassen. |
duration |
UTF8 (VARCHAR) |
BYTE_ARRAY |
Dauer als ISO-8601-Text belassen. |
geopoint |
UTF8 (VARCHAR) |
BYTE_ARRAY |
Geografischer Punkt als Text belassen. |
geojson |
UTF8 (VARCHAR) |
BYTE_ARRAY |
GeoJSON-Geometrie als Text belassen. |
any |
UTF8 (VARCHAR) |
BYTE_ARRAY |
Fallback auf UTF8 für den generischen Typ any. |
Besondere Verhaltensweisen¶
Leere Zellen¶
Leere CSV-Zellen werden für typisierte Spalten als null geschrieben. Alle
Spalten werden daher im Arrow-Schema als nullable deklariert.
Unbekannte Frictionless-Typen¶
Ist ein Feld im Schema mit einem noch nicht unterstützten Typ deklariert, fällt
das Mapping auf string (UTF8) zurück. Dadurch bleibt die Parquet-Erzeugung
stabil, auch wenn Schemas neue Typen enthalten, bevor die Map erweitert wird.
Boolean-Spalten mit ausschließlich null¶
In Apache Arrow erzeugt ein Bool-Vektor, der nur null-Werte enthält, kein
Validity-Bitmap. Das führt beim Schreiben durch parquet-wasm zu einem
Fehler. In diesem Edge-Case fällt das Staging-Backend daher für diese Spalte
auf UTF8 zurück, sodass die Werte weiterhin als null erhalten bleiben.