CSV-, JSON- und Excel-Dateien validieren
Ein praxisnaher Leitfaden zur Validierung von Flat Files — warum Tabellenkalkulationen auf Arten kaputtgehen, die Datenbanken nie zeigen, welche sechs Prüfungen das abfangen und wie Sie denselben Data Contract gegen eine CSV laufen lassen wie gegen Ihr Data Warehouse.
· 10 min read
Um eine CSV-, JSON- oder Excel-Datei zu validieren, laden Sie sie in etwas, das SQL spricht, und führen dann dieselben Prüfungen aus wie gegen eine Warehouse-Tabelle: Nullwerte in Pflichtspalten, doppelte Schlüssel, Werte außerhalb einer erlaubten Menge, Zahlen außerhalb eines plausiblen Bereichs, fehlerhaft formatierte Zeichenketten und veraltete Zeilen. Der Unterschied liegt in dem, was *vor* den Prüfungen passiert. Eine Datenbankspalte hat einen deklarierten Typ und lehnt ein Insert ab; eine Tabellenspalte in einer Kalkulationsdatei hat das, was die letzte Person eingetippt hat. Die meisten Vorfälle mit Flat Files sind Parsing- und Typisierungsprobleme, keine Regelverstöße — die Validierung beginnt also in Wahrheit beim Parsen.
Warum Flat Files anders kaputtgehen
Eine Warehouse-Tabelle hat die schlimmsten Daten bereits abgewiesen, bevor Sie sie sehen. Eine Datei hat nichts abgewiesen.
Es gibt kein Schema, nur eine Vermutung. Jeder CSV-Reader leitet Typen aus den ersten N Zeilen ab. Eine Spalte, die zehntausend Zeilen lang 1, 2, 3 enthält und in Zeile zehntausendeins N/A, ist eine Integer-Spalte — bis sie es plötzlich nicht mehr ist. Ändern Sie die Stichprobengröße, und dieselbe Datei parst anders.
Excel schreibt Ihre Daten still um. Führende Nullen verschwinden aus Postleitzahlen und Artikelnummern, lange Identifier werden zu wissenschaftlicher Notation (1.23457E+14), und alles, was wie ein Datum aussieht, wird eines. Das Problem ist bekannt genug, dass das Komitee für die Benennung menschlicher Gene mehrere Gene umbenannt hat, weil Excel Symbole wie SEPT2 immer wieder in Datumswerte verwandelte. Wenn eine Datei durch Excel gelaufen ist, gehen Sie davon aus, dass unterwegs einige Spalten umformatiert wurden.
Trennzeichen und Quoting sind ebenfalls geraten. Ein semikolongetrennter Export aus einer europäischen Locale, als kommagetrennt gelesen, ergibt eine einzige riesige Spalte. Ein nicht maskiertes Anführungszeichen innerhalb eines Felds verschiebt jede folgende Spalte um eins — und zwar nur für manche Zeilen, was schlimmer ist, als glatt zu scheitern.
Die Kodierung steht nirgends. Eine als Windows-1252 geschriebene und als UTF-8 gelesene Datei macht aus é ein é. Nichts wirft einen Fehler; die Daten sind einfach still falsch.
Der Header muss nicht Zeile 1 sein. Exporte aus Reporting-Tools beginnen regelmäßig mit einer Titelzeile, einer Leerzeile und einer „Erstellt am …"-Zeile vor dem eigentlichen Header.
Nichts davon ist ein Regelverstoß. Alles davon erzeugt eine Datei, die „erfolgreich" zu Unsinn parst — deshalb braucht ein Flat-File-Workflow einen Schritt zum Vorschauen und Bestätigen, bevor irgendeine Regel läuft. Stimmt das Parsen, wird die Aufgabe identisch mit der Validierung einer Warehouse-Tabelle, die der vollständige Leitfaden zur Datenvalidierung im Detail behandelt.
Bringen Sie zuerst das Parsen in Ordnung
Bevor Sie eine einzige Prüfung schreiben, bestätigen Sie vier Dinge:
- Trennzeichen und Anführungszeichen. Komma, Semikolon, Pipe und Tabulator sind alle verbreitet. Schauen Sie in die geparste Vorschau, nicht in den Rohtext.
- Header-Zeile. Steht in Spalte eins
order_idoderVerkaufsexport — Q3? - Abgeleitete Typen. Das ist der Punkt, den alle überspringen. Kam eine Identifier-Spalte als Zahl zurück, haben Sie die führenden Nullen bereits verloren.
- Zeilenzahl. Wenn eine Datei mit 50.000 Zeilen als 3 Zeilen in der Vorschau erscheint, ist das Quoting kaputt.
Catalyst macht daraus einen ausdrücklichen Schritt: Sie laden die Datei hoch, Catalyst parst sie mit DuckDB und zeigt die resultierenden Spalten, die abgeleiteten Typen und eine Zeilenvorschau — und Sie justieren Trennzeichen, Anführungszeichen und Header-Einstellung, bis die Vorschau stimmt. Erst dann wird daraus ein Dataset. Bei .xls und .xlsx wählen Sie zusätzlich das Arbeitsblatt, denn bei einer Arbeitsmappe mit den Reitern Data, Pivot und Notes würde sonst schlicht der erste genommen.
Noch eine Anmerkung speziell zu Identifiern: Wenn eine Spalte ein Code statt einer Menge ist — Bestellnummern, SKUs, Postleitzahlen, Kontonummern —, wollen Sie sie als Text, nicht als Zahl. Es wird nie damit gerechnet, und sie als Zahl zu typisieren ist genau der Weg, auf dem aus 00123 dauerhaft 123 wird.
Die sechs Prüfungen, die jede Datei braucht
Sobald die Datei ein Dataset ist, lässt sie sich mit gewöhnlichem SQL abfragen. Catalyst registriert jede hochgeladene Datei als DuckDB-View, sodass die Validierungs-Engine dasselbe kompilierte SQL ausführt wie gegen Postgres — kein separater Codepfad und keine zweite Regelsprache.
1. Vollständigkeit — Nullwerte in Pflichtspalten
SELECT count(*) AS violations
FROM files.orders_csv
WHERE order_id IS NULL OR trim(order_id) = '';
Prüfen Sie bei Dateien immer auch die leere Zeichenkette, nicht nur NULL. Eine CSV kennt kein Null — ein leeres Feld sind zwei benachbarte Kommas, und Reader unterscheiden sich darin, ob daraus NULL oder '' wird. Die Hälfte Ihrer Zeilen kann leer sein, während eine naive IS NULL-Prüfung perfekte Vollständigkeit meldet.
2. Eindeutigkeit — doppelte Schlüssel
SELECT count(*) AS violations
FROM (
SELECT order_id
FROM files.orders_csv
WHERE order_id IS NOT NULL
GROUP BY order_id
HAVING count(*) > 1
);
Dateien haben keinen Primärschlüssel und keinen Unique-Index, nichts hat also je ein Duplikat verhindert. Die häufigste Ursache ist banal: zwei Exporte mit überlappenden Zeiträumen, aneinandergehängt.
3. Konformität — Werte außerhalb einer erlaubten Menge
SELECT count(*) AS violations
FROM files.orders_csv
WHERE status IS NOT NULL
AND status NOT IN ('pending', 'paid', 'shipped', 'refunded');
Behalten Sie die Null-Absicherung — NULL NOT IN (...) ergibt NULL, diese Zeilen fallen also still aus der Zählung.
Diese Prüfung verdient sich ihren Platz bei Dateien mehr als irgendwo sonst, weil frei eingetippte Spalten in Tabellenkalkulationen driften: paid, Paid, PAID, paid mit Leerzeichen am Ende. Erwägen Sie, in der Regel zu trimmen und in Kleinbuchstaben umzuwandeln, wenn die Quelle von Hand gepflegt wird.
4. Genauigkeit — Zahlen außerhalb eines plausiblen Bereichs
SELECT count(*) AS violations
FROM files.orders_csv
WHERE total_amount IS NOT NULL
AND (total_amount < 0 OR total_amount > 100000);
Achten Sie auf Währungssymbole und Tausendertrennzeichen. €1.234,56 parst in den meisten Readern nicht als Zahl; entweder schlägt es fehl oder es wird zu 1.234. Wenn eine numerische Spalte in der Vorschau als Text zurückkam, liegt es daran.
5. Konformität — fehlerhaft formatierte Identifier
SELECT count(*) AS violations
FROM files.orders_csv
WHERE reference IS NOT NULL
AND NOT regexp_matches(reference, '^ORD-[0-9]{6}#39;);
DuckDB nutzt RE2, verankerte Muster, Zeichenklassen und Quantoren funktionieren also genau so, wie sie geschrieben sind — keine Übersetzung nötig, anders als bei SQL Server. Eine Musterprüfung ist der schnellste Weg, eine von Excel umformatierte Spalte zu erwischen: Wenn aus ORD-000123 ein ORD-123 wurde, schlägt sie an.
6. Aktualität — Freshness
SELECT count(*) AS violations
FROM files.orders_csv
WHERE created_at < now() - INTERVAL 24 HOUR;
Datumswerte sind der gefährlichste Spaltentyp in einem Flat File. 03/04/2026 ist der 3. April oder der 4. März, je nach Locale derjenigen Stelle, die die Datei erzeugt hat — und beides parst fehlerfrei. Wenn eine Datumsspalte zählt, prüfen Sie ihren Wertebereich ausdrücklich: Eine Datei, in der jedes Datum in die ersten zwölf Tage des Monats fällt, ist eine Datei, die mit der falschen Tag-/Monats-Reihenfolge geparst wurde.
Eine Datei gegen Ihr Data Warehouse abgleichen
Die wertvollste Prüfung eines Flat File betrifft oft gar nicht die Datei für sich allein. Eine Lieferantenliste, ein manuelles Korrekturblatt oder ein Finanzexport soll in der Regel mit etwas abgeglichen werden, das Sie bereits halten:
SELECT count(*) AS violations
FROM files.suppliers_xlsx f
LEFT JOIN files.known_suppliers k ON f.supplier_id = k.id
WHERE f.supplier_id IS NOT NULL
AND k.id IS NULL;
Zeilen in der Datei, die es upstream nicht gibt, sind entweder neue Datensätze oder Tippfehler — und zu wissen, welches von beidem, bevor Sie sie laden, ist der ganze Sinn davon, beim Hereinkommen zu validieren statt danach.
Von Ad-hoc-Prüfungen zum Data Contract
Der Grund, eine Datei als Dataset zu behandeln statt als einmaliges Skript, ist, dass Dateien wiederkehren. Dasselbe Lieferantenblatt kommt jeden Monat, von derselben Person, mit denselben Fehlermustern. Die Erwartungen einmal aufzuschreiben heißt, dass der zweite Upload kostenlos mitgeprüft wird.
Catalyst nutzt den Open Data Contract Standard, und ein Datei-Contract sieht genau aus wie ein Warehouse-Contract:
apiVersion: v3.0.0
kind: DataContract
info:
title: orders_csv
version: 1.0.0
owner: finance-ops
schema:
- name: orders_csv
physicalName: orders_csv
physicalType: table
properties:
- name: order_id
logicalType: string
required: true
primaryKey: true
quality:
- rule: nullCount
dimension: completeness
severity: error
mustBe: "0"
- rule: duplicateCount
dimension: uniqueness
severity: error
mustBe: "0"
- name: status
logicalType: string
quality:
- rule: validValues
dimension: conformity
severity: error
mustBe: "['pending', 'paid', 'shipped', 'refunded']"
- name: total_amount
logicalType: number
quality:
- rule: between
dimension: accuracy
severity: error
mustBe: "[0, 100000]"
- name: reference
logicalType: string
quality:
- rule: regex
dimension: conformity
severity: error
mustBe: "'^ORD-[0-9]{6}#39;"
quality:
- rule: rowCount
dimension: consistency
severity: error
mustBe: "> 0"
Zwei Dinge sind erwähnenswert.
Die regex-Regel auf reference steht hier auf Schweregrad error, während die Warehouse-Leitfäden sie auf warning setzen. Diese Umkehrung ist Absicht: In einem Data Warehouse schränkt der Spaltentyp den Wert bereits ein, ein verfehltes Muster ist dort meist eine Eigenheit der Dateneingabe. In einer Datei ist ein verfehltes Muster oft ein Hinweis darauf, dass das *Parsen* schiefgegangen ist — und dafür lohnt es sich anzuhalten.
Auch die rowCount-Regel auf Tabellenebene zählt hier mehr. Ein leeres Ergebnis nach einem Upload bedeutet meistens, dass Trennzeichen oder Blattauswahl falsch waren, und nicht, dass das Geschäft keine Bestellungen hatte.
Praktische Grenzen
Ein paar Dinge, die Sie wissen sollten, bevor Sie einen Workflow darauf ausrichten:
- Uploads sind auf 25 MB pro Datei begrenzt, geprüft gegen die angegebene
Content-Lengthund erneut beim Lesen, da ein Client seine Größe falsch melden kann. Größere Extrakte gehören in ein Data Warehouse. - Unterstützte Formate sind
.csv,.json(Array von Objekten oder NDJSON),.xlsund.xlsx. Tabellenkalkulationen werden beim Upload einmal nach CSV normalisiert, sodass alles Nachgelagerte mit einem einzigen Parse-Pfad arbeitet. - Dateien sind Momentaufnahmen. Ein Dataset zeigt auf die Bytes, die Sie hochgeladen haben; erneutes Hochladen ist ein bewusster Akt. Das ist die richtige Voreinstellung — Sie wollen wissen, wann sich die zugrunde liegenden Daten geändert haben.
- Hochgeladene Dateien werden verschlüsselt gespeichert und nur gelesen, um eine Prüfung zu beantworten.
Stolperfallen bei Flat Files, die man kennen sollte
| Falle | Was passiert | Was zu tun ist |
|---|---|---|
Leere Zeichenkette vs. NULL | Vollständigkeitsprüfung besteht trotz leerer Zeilen | IS NULL OR trim(col) = '' prüfen |
| Führende Nullen entfernt | 00123 wird 123, Joins schlagen fehl | Identifier-Spalten als Text typisieren |
| Wissenschaftliche Notation | Lange IDs werden zu 1.23457E+14 | Als Text typisieren; regex-Regel ergänzen |
| Mehrdeutige Datumswerte | 03/04 parst in beiden Reihenfolgen | Wertebereich der Datumsspalte prüfen |
| Falsches Trennzeichen | Alles landet in einer Spalte | Vorschau vor dem Speichern bestätigen |
| Falsche Kodierung | é wird zu é | Erneut als UTF-8 exportieren |
| Typ aus einer Stichprobe abgeleitet | Ein spätes N/A zerlegt eine numerische Spalte | Abgeleitete Typen in der Vorschau prüfen |
| Titelzeilen über dem Header | Spaltennamen lauten Column1, Column2 | Header-Zeile ausdrücklich setzen |
| Falsches Arbeitsblatt | Es wird der Reiter Notes validiert | Blatt beim Upload auswählen |
Häufige Fragen
Wie validiere ich eine CSV-Datei, ohne Code zu schreiben?
Hochladen, das Parsen bestätigen (Trennzeichen, Anführungszeichen, Header-Zeile, abgeleitete Typen) und dann die Erwartungen deklarieren — Pflichtfeld, Eindeutigkeit, erlaubte Werte, numerischer Bereich, Muster. Catalyst macht aus der Datei ein DuckDB-gestütztes Dataset und kompiliert diese Regeln zu SQL, sodass dasselbe Contract-Format eine CSV und eine Warehouse-Tabelle abdeckt.
Kann ich Excel-Dateien validieren oder muss ich vorher nach CSV konvertieren?
.xls und .xlsx lassen sich direkt hochladen; das Arbeitsblatt wählen Sie beim Upload. Die Datei wird beim Ingest einmal nach CSV normalisiert, sodass alles Nachgelagerte einen einzigen Parse-Pfad hat. Beachten Sie: Alles, was Excel angefasst hat, kann bereits umformatiert worden sein — entfernte führende Nullen, wissenschaftliche Notation, autokorrigierte Datumswerte — und genau dafür sind die Muster- und Bereichsregeln da.
Warum besteht meine CSV-Validierung, obwohl die Daten offensichtlich falsch sind?
Fast immer, weil das Parsen falsch ist und nicht die Regeln. Die üblichen Ursachen: Ein leeres Feld wurde zu '' statt zu NULL, die Vollständigkeitsprüfung sah also einen Wert; das falsche Trennzeichen hat alles in eine Spalte gepackt, die geprüfte Spalte ist also leer und jede Null-Absicherung hat sie übersprungen; oder eine als Text abgeleitete Spalte lässt eine numerische Bereichsregel Zeichenketten vergleichen. Prüfen Sie die geparste Vorschau, bevor Sie einem bestandenen Lauf trauen.
Wie groß darf eine Datei sein, die ich validiere?
Catalyst begrenzt Uploads auf 25 MB pro Datei, was die meisten manuellen Exporte, Referenzblätter und Lieferantenlisten abdeckt. Darüber hinaus gehört die Datei wirklich in ein Data Warehouse — laden Sie sie nach PostgreSQL oder BigQuery und validieren Sie sie dort, wo Partition Pruning und Indizes die Prüfungen billig machen.
Unterscheidet sich die Validierung einer Datei von der einer Datenbanktabelle?
Die Regeln sind identisch — derselbe Contract, dieselben sechs Prüfungen. Was sich unterscheidet, ist alles davor. Eine Datenbank hat Typen bereits durchgesetzt und fehlerhafte Zeilen abgewiesen; eine Datei hat nichts durchgesetzt, Parsen und Typisierung sind also der Ort, an dem die meisten Mängel sitzen. Stimmt das Parsen, ist der Rest dieselbe Arbeit.