我有一个包含以下内容的CSV文件:
id,value
123,{"M":{"name_1":{"S":"value_1"}, "name_2":{"S":"value_2"}}}
我正在尝试读取此CSV文件,并通过以下方式在DynamoDB中创建记录:
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]
}
}
然而,这段代码不起作用,我找不到任何关于如何从CSV文件中读取双引号值的示例,而jsondecode
可以创建适当的JSON结构。有人知道怎么做吗?
2条答案
按热度按时间8fsztsew1#
清理你的csv文件:
然后:
fzsnzjdm2#
您在这里展示的文档并不是Terraform函数想要解析的通常意义上的CSV文档,它是在RFC 4180中定义的格式。您的第二个“field”似乎是一个JSON文档,其中包含自己的字段,包括逗号,这意味着
csvdecode
将误解此文档的意图。相反,我认为这是一种自定义格式,因此使用更简单的原语解析它:
上面使用了不同Terraform函数的混合来将文件内容拆分为较小的令牌:
split
将整个内容拆分为单独的行(chomp
用于处理Windows风格的行结尾的可能性,这将是\r\n
而不仅仅是\n
,因此之后需要额外的剥离。slice
丢弃第一行,即“header”行。regex
将“id”和“values”字段分开,忽略“values”字段中多余的逗号和引号。jsondecode
将“values”字符串替换为它使用JSON语法描述的对象。我将其拆分为多个步骤,以便更容易地查看中间步骤的结果,但如果您愿意,您应该能够将其中至少一些步骤组合在一起形成更大的表达式。
在所有这些之后,
local.custom_data
应该是一个可以与for_each
一起使用的数据结构,形状如下:如果你想把它当作一个普通的CSV文档,并使用
csvdecode
,那么你需要首先改变“value”字段的编码,以转义引号和逗号,这意味着:"
中,如RFC 4180第2节第6项所述。""
而不是"
),如RFC 4180第2节第7项所述。原则上可以使用Terraform本身执行这种转换,但它与我上面展示的较低级别的解析基本相同,首先分别标记id和value字段,所以我不会选择这个选项,除非我可以改变生成原始文档的系统来生成有效的CSV数据本身,这样Terraform就可以只依赖于
csvdecode
。