Как создать переменные с областью итераций внутри действий ForEach в фабрике данных Azure

У меня есть ForEach действие, в котором внутри каждой итерации мне нужно установить несколько переменных, специфичных для итерации. Я могу добиться этого, используя переменные, определенные для конвейера (область конвейера), но это заставляет меня запускать цикл в режиме Sequential, чтобы несколько итераций, выполняемых параллельно, не обновляли одну и ту же переменную. Что мне действительно нужно, так это возможность определять эти переменные в каждой итерации (объем итерации), чтобы я мог выполнять действие ForEach в параллельном режиме.

введите описание изображения здесь

введите описание изображения здесь

Я подумал о создании набора данных SQL, в котором я мог бы выполнять поиск поддельных значений (SELECT 1 AS var1, 2 AS var2), просто чтобы получить структуру, в которой я могу устанавливать и использовать эти значения, но это кажется действительно неуместным. Я также рассматривал возможность использования типа переменной массива с параметром AppendVariable, но это вводит много настраиваемого синтаксического анализа.

Было бы неплохо, если бы я мог просто иметь набор данных InMemory, который не должен быть привязан к источнику данных, где я мог бы использовать его как структуру внутри моей итерации ForEach. Есть ли у кого-нибудь другие идеи о том, как установить переменные, специфичные для итерации, внутри цикла ForEach?


person Geekn    schedule 08.08.2020    source источник
comment
Вау, правда ли это? Фактически, вы не можете использовать переменные внутри циклов ForEach, которые выполняются параллельно? Это где-то задокументировано?   -  person Martin Wickman    schedule 08.02.2021
comment
Я считаю, что это все еще правда. В настоящее время переменные объявляются на уровне конвейера (подумайте о переменных уровня класса).   -  person Geekn    schedule 10.02.2021
comment
@MartinWickman Это задокументировано где-то в MSDN - я помню, как наткнулся на это несколько дней назад. Хотя это не очевидно - он где-то закопан в несколько абзацев на странице.   -  person Brondahl    schedule 12.03.2021


Ответы (2)


О лучшем способе сделать это в настоящее время - это извлечь значения из внешнего поиска или получить активность метаданных, если это возможно. использование внутреннего поиска не было бы таким рентабельным или эффективным с точки зрения производительности. особенно если вы повторяли более 100 или тысяч. Конечно, это если вы можете заранее определить значения для каждой итерации. если не можешь, то. Я бы выбрал ваш поисковый подход. или, если вы можете полностью уйти от переменных, просто установите значения, используя выражение, использующее динамические свойства.

person Jason Horner    schedule 12.08.2020
comment
Я не знаю заранее значение, поэтому у меня есть этот переключатель внутри цикла. Я, вероятно, мог бы написать какое-нибудь огромное выражение, которое является эквивалентом оператора switch для каждой переменной, но мне кажется, что это будет довольно некрасиво и сложно поддерживать. Использование переключателя для обработки всех различных способов, которыми может быть установлена ​​переменная, казалось более легким для чтения, так что хранимую процедуру можно было просто понять, просто сославшись на переменную. - person Geekn; 13.08.2020
comment
Если я создам поддельный поиск по набору данных, смогу ли я записать в него значения? Как я бы сделал фальшивый SELECT NULL AS var1, NULL AS var2, а затем записал реальное значение в поля набора данных / var1 и набора данных / var2: output.firstRow.var1 = 'myData' - person Geekn; 13.08.2020
comment
Не уверен, что я полностью понимаю, что поиск может возвращать любые значения, которые вы хотите ... включая создание их на основе выражений, но это возвращаемое значение становится неизменным ... не видя других ветвей переключателя и выражения переключателя, похоже, что он мог бы Работа. - person Jason Horner; 13.08.2020
comment
Думаю, я понимаю, о чем вы говорите, поэтому не думаю, что это сработает. Вот выражение, которое я использую в одном из операторов switch, где я просто беру первые четыре символа имени файла, чтобы получить код @substring (activity ('GetFileMetadata'). Output.itemName, 0, 4). В другом случае он может быть в середине имени файла, а в другом его может вообще не быть (зависит от источника файла ... отсюда и переключатель). Поэтому, если можно выполнить поиск по файлу, то каждое выражение SetExpression можно заменить поиском в файле, возможно, если я вас правильно понимаю. - person Geekn; 13.08.2020
comment
Это кажется более сложным, чем должно быть, так что, возможно, я просто чего-то не понимаю. В конце концов, все, что мне нужно, - это место для хранения вычисленных значений на основе условия в цикле, а затем использовать их в более поздних действиях. - person Geekn; 13.08.2020
comment
В итоге я просто переместил всю эту логику в хранимую процедуру и выполнил поиск по ней. Спасибо за помощь - person Geekn; 13.08.2020

Согласен, это очень раздражает и раздражает.

Если первая часть ответа Джейсона подходит для вашей ситуации, то это определенно правильный путь. (Определите переменные вне цикла).

Но если предположить, что переменные вычисляются динамически для каждой итерации, то единственное известное мне решение - определить тело цикла Foreach как его собственный конвейер. Теперь вы можете определить переменную внутри этого внутреннего конвейера, которая ограничена отдельными исполнениями внутреннего конвейера.

Таким образом можно обойти довольно много ограничений конвейера ADF. Вложенные If / Foreaches, ограничения активности и т. Д.

person Brondahl    schedule 12.03.2021
comment
Я бы поступил так же: определил внутренний конвейер и передал в это исполнение значения, зависящие от итерации. - person Jason Welch; 14.03.2021