ADF :: Как заменить файлы в хранилище BLOB-объектов
В разделе «Управление затратами Azure» > «Экспорт» есть экспорт под названиемDaily export of month-to-date
:
Такой экспорт происходит ежедневно и экспортируется в хранилище BLOB-объектов.
ПРОБЛЕМА: поскольку это ежемесячный экспорт, если сегодня 26 или апрель, сегодня будет создан файл .csv со всей информацией об управлении затратами с 1 по 26 апреля.
Но завтра будет сгенерирован еще один файл .csv со всеми затратами с 1 по 27 апреля.
Таким образом, у меня будет двойная информация!
ЦЕЛЬ: идеальным решением было бы, чтобы как только новый файл был экспортирован в эту учетную запись хранения, старый файл был удален.
Таким образом, всегда существует только один файл .csv, содержащий все данные за текущий месяц.
ОБЪЕМ: Все может быть в объеме:
- Фабрика данных Azure
- Логические приложения
- Учетные записи автоматизации
- Мощность автоматизировать
... все, что работает.
2 ответа
Я воспроизвел в своей среде и получил ожидаемые результаты, как показано ниже:
Дизайн:
Понятно: вы можете воспроизвести приведенный выше дизайн с помощью приведенного ниже кода:
Код приложения логики:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Delete_blob_(V2)": {
"inputs": {
"headers": {
"SkipDeleteIfFileNotFoundOnServer": false
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "delete",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files/@{encodeURIComponent(encodeURIComponent('/rithwik/',variables('ammo')))}"
},
"runAfter": {
"For_each": [
"Succeeded",
"Failed"
]
},
"type": "ApiConnection"
},
"For_each": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "emo",
"value": "@triggerBody()?['LastModified']"
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Append_to_array_variable_2": {
"inputs": {
"name": "vammo",
"value": "@items('For_each')?['DisplayName']"
},
"runAfter": {
"Append_to_array_variable": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Compose": {
"inputs": "@items('For_each')?['LastModified']",
"runAfter": {},
"type": "Compose"
},
"Condition": {
"actions": {
"Append_to_string_variable": {
"inputs": {
"name": "ammo",
"value": "@variables('vammo')[0]"
},
"runAfter": {},
"type": "AppendToStringVariable"
}
},
"else": {
"actions": {
"Append_to_string_variable_2": {
"inputs": {
"name": "ammo",
"value": "@variables('vammo')[1]"
},
"runAfter": {},
"type": "AppendToStringVariable"
}
}
},
"expression": {
"and": [
{
"less": [
"@ticks(variables('emo')[0])",
"@ticks(variables('emo')[1])"
]
}
]
},
"runAfter": {
"Append_to_array_variable_2": [
"Succeeded"
]
},
"type": "If"
}
},
"foreach": "@body('Lists_blobs_(V2)')?['value']",
"runAfter": {
"Initialize_variable_3": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "emo",
"type": "array"
}
]
},
"runAfter": {
"Lists_blobs_(V2)": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "vammo",
"type": "array"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_3": {
"inputs": {
"variables": [
{
"name": "ammo",
"type": "string"
}
]
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Lists_blobs_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/foldersV2/@{encodeURIComponent(encodeURIComponent('JTJmcml0aHdpaw=='))}",
"queries": {
"nextPageMarker": "",
"useFlatListing": false
}
},
"metadata": {
"JTJmcml0aHdpaw==": "/rithwik"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"When_a_blob_is_added_or_modified_(properties_only)_(V2)_2": {
"evaluatedRecurrence": {
"frequency": "Second",
"interval": 3
},
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/triggers/batch/onupdatedfile",
"queries": {
"checkBothCreatedAndModifiedDateTime": false,
"folderId": "JTJmcml0aHdpaw==",
"maxFileCount": 1
}
},
"metadata": {
"JTJmcml0aHdpaw==": "/rithwik"
},
"recurrence": {
"frequency": "Second",
"interval": 3
},
"splitOn": "@triggerBody()",
"type": "ApiConnection"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob": {
"connectionId": "/subscriptions/b83c1ed3-c5b6-74c23f/resourceGroups/rbojja-/providers/Microsoft.Web/connections/azureblob",
"connectionName": "azureblob",
"id": "/subscriptions/b8b-b5ba-2074c23f/providers/Microsoft.Web/locations/eastus/managedApis/azureblob"
}
}
}
}
}
Сначала создайте 1 объект, как показано ниже:
Blob может быть любого типа.
Затем загрузил новый Blob:
Затем blob был удален:
Выход:
Также добавлено несколько новых шагов для большей точности: Просмотр кода:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Delete_blob_(V2)": {
"inputs": {
"headers": {
"SkipDeleteIfFileNotFoundOnServer": false
},
"host": {
"connection": {
"name": "@parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "delete",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files/@{encodeURIComponent(encodeURIComponent('/rithwik/',variables('xyz')))}"
},
"runAfter": {
"Initialize_variable_4": [
"Succeeded",
"Failed"
]
},
"type": "ApiConnection"
},
"For_each": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "emo",
"value": "@triggerBody()?['LastModified']"
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Append_to_array_variable_2": {
"inputs": {
"name": "vammo",
"value": "@items('For_each')?['DisplayName']"
},
"runAfter": {
"Append_to_array_variable": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Compose": {
"inputs": "@items('For_each')?['LastModified']",
"runAfter": {},
"type": "Compose"
},
"Condition": {
"actions": {
"Append_to_string_variable": {
"inputs": {
"name": "ammo",
"value": "@variables('vammo')[0]"
},
"runAfter": {},
"type": "AppendToStringVariable"
}
},
"else": {
"actions": {
"Compose_2": {
"inputs": "@variables('vammo')[1]",
"runAfter": {},
"type": "Compose"
},
"Set_variable": {
"inputs": {
"name": "ammo",
"value": "@{outputs('Compose_2')}"
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "SetVariable"
}
}
},
"expression": {
"and": [
{
"less": [
"@ticks(variables('emo')[0])",
"@ticks(variables('emo')[1])"
]
}
]
},
"runAfter": {
"Append_to_array_variable_2": [
"Succeeded"
]
},
"type": "If"
}
},
"foreach": "@body('Lists_blobs_(V2)')?['value']",
"runAfter": {
"Initialize_variable_3": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "emo",
"type": "array"
}
]
},
"runAfter": {
"Lists_blobs_(V2)": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "vammo",
"type": "array"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_3": {
"inputs": {
"variables": [
{
"name": "ammo",
"type": "string"
}
]
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_4": {
"inputs": {
"variables": [
{
"name": "xyz",
"type": "string",
"value": "@variables('ammo')"
}
]
},
"runAfter": {
"For_each": [
"Succeeded",
"Failed"
]
},
"type": "InitializeVariable"
},
"Lists_blobs_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/foldersV2/@{encodeURIComponent(encodeURIComponent('JTJmcml0aHdpaw=='))}",
"queries": {
"nextPageMarker": "",
"useFlatListing": false
}
},
"metadata": {
"JTJmcml0aHdpaw==": "/rithwik"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"When_a_blob_is_added_or_modified_(properties_only)_(V2)_2": {
"evaluatedRecurrence": {
"frequency": "Second",
"interval": 3
},
"inputs": {
"host": {
"connection": {
"name": "@parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/triggers/batch/onupdatedfile",
"queries": {
"checkBothCreatedAndModifiedDateTime": false,
"folderId": "JTJmcml0aHdpaw==",
"maxFileCount": 1
}
},
"metadata": {
"JTJmcml0aHdpaw==": "/rithwik"
},
"recurrence": {
"frequency": "Second",
"interval": 3
},
"splitOn": "@triggerBody()",
"type": "ApiConnection"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob": {
"connectionId": "/subscriptions/b8074c23f/resourceGroups/bojja/providers/Microsoft.Web/connections/azureblob",
"connectionName": "azureblob",
"id": "/subscriptions/b83c1ed3-c574c23f/providers/Microsoft.Web/locations/eastus/managedApis/azureblob"
}
}
}
}
}
При использовании хранилища BLOB-объектов запись файла с тем же именем в то же место автоматически перезапишет существующий. Я не слишком хорошо знаком с управлением затратами, но вы можете использовать конвейер ADF и установить приемник в качестве контейнера учетной записи хранения BLOB-объектов и убедиться, что файл имеет то же имя, чтобы он автоматически перезаписывал существующий, например fileApril.csv перезапишет fileApril. .csv. Вы также можете установить параметры в ADF, чтобы изменить соглашение об именах, чтобы сохранить управление версиями, например, использование динамического параметра date() должно позволить вам хранить файл в месяц в зависимости от того, когда был запущен конвейер.