Eu tenho um arquivo CSV que contém o seguinte conteúdo:
id,value
123,{"M":{"name_1":{"S":"value_1"}, "name_2":{"S":"value_2"}}}
Estou tentando ler esse arquivo CSV e criar registros no DynamoDB da seguinte forma:
locals {
custom_data = csvdecode(file("${path.module}/../custom_data.csv"))
}
resource "aws_dynamodb_table_item" "custom_table_item" {
for_each = {for row in local.custom_data : row.id => row}
table_name = aws_dynamodb_table.custom_table.name
hash_key = aws_dynamodb_table.custom_table.hash_key
item = jsonencode({
"id" : { "S" : each.value.id },
"value" : jsondecode(each.value.value)
})
lifecycle {
ignore_changes = [item]
}
}
No entanto, esse código não funciona e não consigo encontrar nenhum exemplo de como ler os valores entre aspas duplas do arquivo CSV de uma forma que jsondecode
possa criar a estrutura JSON apropriada. Alguém sabe como fazer isso?
Higienize seu arquivo csv:
então:
O documento que você mostrou aqui não é realmente um documento CSV no sentido usual que a função do Terraform pretende analisar, que é o formato definido em RFC 4180 . Seu segundo "campo" parece ser um documento JSON com seus próprios campos, incluindo vírgulas, o que significa que você
csvdecode
não entenderá o que este documento pretende significar.Em vez disso, consideraria este um formato personalizado e o analisaria usando primitivos mais simples:
O texto acima usa uma mistura de diferentes funções do Terraform para dividir o conteúdo do arquivo em tokens menores:
split
para dividir todo o conteúdo em linhas individuais (parachomp
lidar com a possibilidade de finais de linha no estilo do Windows, que seriam\r\n
em vez de apenas\n
e, portanto, precisariam de remoção extra posteriormente).slice
para descartar a primeira linha, que é a linha de "cabeçalho".regex
para separar os campos "id" e "valores" de uma forma que ignore as vírgulas e aspas extras no campo "valores".jsondecode
substitua a string "valores" pelo objeto que ela está descrevendo usando a sintaxe JSON.Dividi isso em várias etapas para facilitar a visualização dos resultados das etapas intermediárias, mas você poderá combinar pelo menos algumas dessas etapas em expressões maiores, se preferir.
Depois de tudo isso,
local.custom_data
deve haver uma estrutura de dados que você possa usarfor_each
, com o seguinte formato:Se você quiser tratar isso como um documento CSV normal e usá-lo,
csvdecode
primeiro você precisará alterar a codificação dos campos "valor" para escapar das aspas e vírgulas, o que significa:"
, conforme descrito na RFC 4180 seção 2 item 6.""
em vez de apenas"
), conforme descrito na seção 2, item 7, da RFC 4180.Em princípio, seria possível realizar essa transformação usando o próprio Terraform, mas seria basicamente o mesmo que a análise de nível inferior que mostrei acima para primeiro tokenizar os campos id e valor separadamente, então eu não escolheria esta opção a menos que eu pode alterar qualquer sistema que esteja gerando o documento original para produzir dados CSV válidos, de modo que o Terraform possa contar apenas com arquivos
csvdecode
.