#azure #azure-data-factory #azure-data-factory-2
Вопрос:
Я пытаюсь скопировать данные из csv
файлов, найденных в Azure Datalake, в таблицу в SQL Server. В качестве условия я хочу копировать файлы, которых еще нет в базе данных, только с помощью столбца имени файла, найденного в таблице базы данных. Ниже приведена моя попытка (я не смог найти пример этого в Интернете).
Сначала я использую Get Metadata
действие, которое извлекает все файлы, находящиеся в озере данных. Одновременно я использую Lookup
действие, которое получает различные имена файлов в таблице выбора. На первом изображении показана организация деятельности.
Вот результаты деятельности Get Metadata
и. Lookup
Вывод метаданных файлов сбора данных
{
"childItems": [
{
"name": "surveydetails_eq5d_001.csv",
"type": "File"
},
{
"name": "surveydetails_koos_001.csv",
"type": "File"
},
{
"name": "surveydetails_oxford_001.csv",
"type": "File"
},
{
"name": "surveydetails_womac_001.csv",
"type": "File"
}
],
Поиск файла таблицы базы данных
{
"count": 4,
"value": [
{
"file_name": "surveydetails_koos_001.csv"
},
{
"file_name": "surveydetails_oxford_001.csv"
},
{
"file_name": "surveydetails_eq5d_001.csv"
},
{
"file_name": "surveydetails_womac_001.csv"
}
],
Как только у меня будут имена файлов, я использую a ForEach
и повторяю элементы Datalake:
@activity('Datalake Files Metadata').output.childitems
Внутри у ForEach
меня есть IfCondition
приложение, которое проверяет, находится ли текущий файл Datalake в массиве поиска. Если файла Datalake нет в массиве, выполняется операция копирования. Однако с помощью этой конструкции я бы не ожидал, что что-то будет скопировано, так как элементы в datalake уже находятся в базе данных. У меня такое чувство, что динамический контент в IfCondition
нем отключен, но после поиска в Интернете в течение последних нескольких часов я не могу найти никаких очевидных ошибок. Есть ли логика в выключении IfCondition? Это что-то другое? Пожалуйста, помогите.
Логика для IfCondition
:
@not(contains(activity('Database Table File Lookup').output.value, item().name))
Комментарии:
1. Отличный вопрос! Очень подробно. У меня похожая проблема. Надеюсь, вы скоро получите ответ 😉
Ответ №1:
Логика Ifcondition содержит элемент().name, который возвращает строку, равную имени файла(Пример —> «surveydetails_eq5d_001.csv»).
Однако действие(«Поиск файла таблицы базы данных»). output.value возвращает массив словарей. В словарях есть «имя_файла» имя файла. то есть
[
{
"file_name": "surveydetails_eq5d_001.csv"
},
{
"file_name": "surveydetails_koos_001.csv"
},
{
"file_name": "surveydetails_oxford_001.csv"
},
{
"file_name": "surveydetails_womac_001.csv"
}
]
Вот почему условие IF не выполняется.
Что вы можете попробовать, так это создать 2 новых массива переменных dblist и mytemparray. Выполните итерацию по массиву действия («Поиск файла таблицы базы данных»). вывод.значение и извлеките каждое имя файла в свой новый массив dblist(для этого вы можете использовать «объединение»). Затем вы можете использовать этот массив в своей проверке Ifcondition. Не забудьте установить переключатель «Последовательный» в положение ВКЛ в цикле for. Смотрите снимок экрана.
Внутри моего цикла for у меня есть 2 набора переменных действий.
- Упражнение 1 : Скопируйте список dblist в mytemparray
- Действие 2 : Объедините mytemparray с именем файла и сохраните в dblist @union(переменные(‘mytemparray’),массив(элемент().имя файла))
Комментарии:
1. Полезно, но сложность циклов не идеальна.
Ответ №2:
Основываясь на некоторой информации Microsoft о выражениях и комментарии @anupam, я преобразовал массив в строку, чтобы сравнить строку с подстрокой. Это упрощает ответ @Anupams, потому что другой forEach
ответ не требуется.
@not(contains(string(activity('Survey Details File Lookup').output.value), item().name))