2016-11-09 4 views
2

У меня есть сценарий USQL и экстрактор CSV для загрузки моих файлов. Однако в течение нескольких месяцев файлы могут содержать 4 столбца, а несколько месяцев они могут содержать 5 столбцов.Обработка файлов с различными столбцами в USQL

Если я настроил свой экстрактор со списком столбцов для 4 или 5 полей, я получаю сообщение об ожидаемой ширине файла. Перейдите проверки разделителей и т. Д. Не удивительно.

Какова работа с этой проблемой, пожалуйста, при условии, что USQL все еще находится в новичке и не хватает какой-либо базовой обработки ошибок?

Я пробовал использовать предложение о отключении в экстракторе, чтобы игнорировать более широкие столбцы, которые удобны для 4 столбцов. Затем получаем количество строк набора строк с условием IF, которое затем имеет экстрактор для 5 столбцов. Однако это приводит к тому, что мир переменных набора строк не используется как скалярные переменные в выражении IF.

Кроме того, я попробовал подсчет стиля C# и sizeof (@ AttemptExtractWith4Cols). Ни одна из них не работает.

Фрагмент кода, чтобы дать вам почувствовать подход я везу:

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 

Конечно, если есть такая вещь, как TRY CATCH блока в USQL это было бы намного проще.

Это даже разумный подход?

Любой вход был бы оценен.

Спасибо за ваше время.

ответ

2

U-SQL теперь поддерживает OUTER UNION, так что вы можете справиться с этим, как это:

// 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(); 

В моем примере, file1 4 колонки и file2 имеет 5 столбцов. Скрипт успешно выполняется в любом сценарии.

Мои результаты:

U-SQL results

Надежда, что имеет смысл.

2

ВНЕШНИЙ СОЮЗ - отличное решение. Кроме того, вы также можете написать свой собственный генератор, если вы ожидаете, что ваши строки в файле будут разными. См. Пример this blog post.

+0

Спасибо, Майк, я посмотрю. –

Смежные вопросы