Как выводить несколько файлов динамически с помощью пользовательских экстракторов U-SQL?

2

Я создал запрос U-SQL, который считывает данные из нескольких файлов. Теперь я должен выводить данные в нескольких файлах в другой папке. У меня есть приведенный ниже пример,

Выход U-SQL в Azure Data Lake

Используемый ниже сценарий,

        DECLARE @storagePath string = @"E:\";
        DECLARE @inputFileSetName string = @"dbo.file{*}.tsv"; 
        DECLARE @outputFileName string = @"dbo.files.csv";

        DECLARE @input string = String.Concat(@storagePath, 
        @inputFileSetName);
        DECLARE @output = string.Concat(@storagePath, @outputFileName);
        @searchlog =
        EXTRACT Id string,
        Name string,
        Address string

        FROM @input
        USING new USQLApplication3.SampleExtractor(Encoding.UTF8);
        @transactions =
        SELECT *,
        ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Id DESC) AS 
        RowNumber_12345
        FROM @searchlog;

       @result =
       SELECT EXTRACT Id,
        Name,
        Address 
       FROM @transactions
       WHERE RowNumber_12345 == 1;

       OUTPUT @result 
       TO @output
       USING Outputters.Csv(encoding : Encoding.UTF8, quoting : false);

Ниже приведен код С# для пользовательских экстракторов,

public class SampleExtractor : IExtractor
{
    private Encoding _encoding;
    private byte[] _row_delim;
    private char _col_delim;

    public SampleExtractor(Encoding encoding, string row_delim = "\n", char col_delim = '\t')
    {
        this._encoding = ((encoding == null) ? Encoding.UTF8 : encoding);
        this._row_delim = this._encoding.GetBytes(row_delim);
        this._col_delim = col_delim;
    }

    public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
    {
        string line;
        //Read the input line by line
        foreach (Stream current in input.Split(_encoding.GetBytes("\n")))
        {
            using (StreamReader streamReader = new StreamReader(current, this._encoding))
            {
                line = streamReader.ReadToEnd().Trim();
                //Split the input by the column delimiter
                string[] parts = line.Split(this._col_delim);
                foreach (string part in parts)
                {
                    string res = part;
                    if (res != null)
                    {
                        res = "\"" + res.Replace("\"", "\"\"") + "\"";
                    }
                    output.Set<string>(count, res);
                }

            }
            yield return output.AsReadOnly();

        }
       yield break;
    }
}

Как я могу динамически создавать несколько файлов на выходе? На данный момент он создает только один файл.

Отредактировано:

Я также попытался с несколькими выводами в одном сценарии u-sql,

      @x = SELECT * FROM (VALUES( "A", 10, 20), ("A", 11, 21), ("B", 10, 30), ("B", 100, 200)) AS T(name, value1, value2);

     // Generate the script to do partitioned output based on name column:
     DECLARE @out string ="E:/genscript.usql";
     @stmts = 
         SELECT "@res=SELECT value1, value2 FROM @x WHERE name == 
         \""+name+"\"; 
     OUTPUT 
          @res TO \"E:/"+name+".csv\" USING Outputters.Csv();" AS output 
          FROM (SELECT DISTINCT name FROM @x) AS x;

     OUTPUT @stmts TO @out
           USING Outputters.Text(delimiter:' ', quoting:false);

     @path = EXTRACT path string FROM @out USING Extractors.Text() ;
     OUTPUT @path  TO "E:/{*}.usql" 
           USING Outputters.Text(delimiter:' ', quoting:false);

Но он показывает следующую ошибку,

Код степени серьезности Описание Ошибка состояния подавления строки файла проекта E_CSC_USER_READFROMPREVIOUSOUTPUT: оператор EXTRACT считывает/ссылается из местоположения E:\genscript.usql, который является объектом предыдущего оператора OUTPUT. Описание: Компилятор не поддерживает OUTPUT, а затем чтение/реферирование из одного файла в одном задании. Разрешение. Пожалуйста, сделайте одно задание для OUTPUT для файла и другое задание для чтения/ссылки на тот же файл.

Что мне теперь делать для вывода нескольких файлов из одного u-sql или как я могу получить доступ к другому файлу скрипта u-sql из текущего сценария u-sql?

  • 0
    вам, вероятно, нужно создать JOB, который делает только 1 запись за раз. затем параметризуйте его, и для каждой записи у вас будет выход
Теги:
azure
azure-data-lake
u-sql

1 ответ

1

Вы можете просто использовать несколько команд OUTPUT, например

OUTPUT @result1
TO @output1
USING Outputters.Csv(encoding : Encoding.UTF8, quoting : false);

OUTPUT @result2
TO @output2
USING Outputters.Csv(encoding : Encoding.UTF8, quoting : false);
...

U-SQL не поддерживает динамический U-SQL напрямую, но есть способы сделать это. Два примера его использования - здесь и здесь.

  • 2
    Привет, я должен создать его динамически в зависимости от количества строк во входном файле.
  • 0
    В первом примере stackoverflow.com/questions/43227421/…
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню