2016-11-09 9 views
2

Ich habe ein USQL-Skript und CSV-Extraktor, um meine Dateien zu laden. In einigen Monaten können die Dateien jedoch 4 Spalten enthalten und einige Monate können sie 5 Spalten enthalten.Umgang mit Dateien mit verschiedenen Spalten in USQL

Wenn ich meinen Extraktor mit einer Spaltenliste für entweder 4 oder 5 Felder einrichte, erhalte ich einen Fehler über die erwartete Breite der Datei. Go check delimiters etc usw. Keine Überraschung.

Was ist die Arbeit um dieses Problem, bitte gegeben USQL ist immer noch in einem Anfänger und einige grundlegende Fehlerbehandlung fehlt?

Ich habe versucht, die Silent Klausel im Extraktor verwenden, um breitere Spalten zu ignorieren, die für 4 Spalten praktisch ist. Dann wird eine Zeilenanzahl des Rowsets mit einer IF-Bedingung abgerufen, die dann einen Extraktor für 5 Spalten enthält. Dies führt jedoch zu einer Welt von Rowset-Variablen, die im IF-Ausdruck nicht als Skalarvariablen verwendet werden.

Auch ich habe versucht, eine C# -Stil Anzahl und eine Größe von (@ AttemptExtractWith4Cols). Keine Arbeit.

-Code-Schnipsel Ihnen ein Gefühl für den Ansatz zu geben, ich nehme:

DECLARE @SomeFilePath string = @"/MonthlyFile.csv"; 

@AttemptExtractWith4Cols = 
    EXTRACT Col1 string, 
      Col2 string, 
      Col3 string, 
      Col4 string 
    FROM @SomeFilePath 
    USING Extractors.Csv(silent : true); //can't be good. 

//can't assign rowset to scalar variable! 
DECLARE @RowSetCount int = (SELECT COUNT(*) FROM @AttemptExtractWith4Cols); 

//tells me @AttemptExtractWith4Cols doesn't exist in the current context! 
DECLARE @RowSetCount int = @AttemptExtractWith4Cols.Count(); 

IF (@RowSetCount == 0) THEN 
    @AttemptExtractWith5Cols = 
     EXTRACT Col1 string, 
       Col2 string, 
       Col3 string, 
       Col4 string, 
       Col5 string 
     FROM @SomeFilePath 
     USING Extractors.Csv(); //not silent 
END; 


//etc 

Natürlich, wenn es so etwas wie ein TRY-Block CATCH ist in USQL diesem wäre viel einfacher sein.

Ist das überhaupt ein vernünftiger Ansatz?

Jede Eingabe würde sehr geschätzt werden.

Vielen Dank für Ihre Zeit.

Antwort

2

U-SQL unterstützt nun OUTER UNION, so dass Sie es so handhaben kann:

// Scenario 1; file has 4 columns 
DECLARE @file1 string = @"/input/file1.csv"; 

// Scenario 2; file has 5 columns 
//DECLARE @file1 string = @"/input/file2.csv"; 


@file = 
    EXTRACT col1 string, 
      col2 string, 
      col3 string, 
      col4 string 
    FROM @file1 
    USING Extractors.Csv(silent : true) 

    OUTER UNION ALL BY NAME ON (col1, col2, col3, col4) 

    EXTRACT col1 string, 
      col2 string, 
      col3 string, 
      col4 string, 
      col5 string 
    FROM @file1 
    USING Extractors.Csv(silent : true); 


@output = 
    SELECT * 
    FROM @file; 


OUTPUT @output 
    TO "/output/output.csv" 
USING Outputters.Csv(); 

In meinem Beispiel file1 hat 4 Spalten und Datei2 hat 5 Spalten. Das Skript wird in beiden Szenarien erfolgreich ausgeführt.

Meine Ergebnisse:

U-SQL results

Hoffnung, die Sinn macht.

2

Die OUTER UNION ist eine großartige Lösung. Alternativ können Sie auch Ihren eigenen generischen Extraktor schreiben, wenn Sie erwarten, dass Ihre Zeilen in einer Datei unterschiedlich sind. Ein Beispiel finden Sie in this blog post.

+0

Danke Mike, ich werde es mir ansehen. –

Verwandte Themen