如何从CSV中获取数据并插入Elixir中的Postgres

时间:2018-03-19 04:49:10

标签: elixir phoenix-framework

我正在使用CSV模块导入CSV文件,这会将数据存储在地图中,一切正常,从而为我提供了常用的数据映射结果。然后,我需要获取该映射数据并将其发送到ecto.repo。这是使用标准的attrs参数,然后解压缩并发送到变更集以发送到数据库。如何迭代每个键并返回值,然后获取每个子值并将其传递给ecto.repo.create_object?

%{{:ok, ["key", "key", "key"]} => {:ok, ["value", "value", "value"}}..}

所有键和值的映射完全相同,因此每个键的值与值相同。另一件事是,我不知道密钥的名称,所以我无法拨打每个密钥。此外,每组键值对都是CSV文件中的一个单独的行,我需要将每行传递到ecto.repo.create_object以输入数据库。基本上为CSV文件的每一行创建一条新记录。实现这一目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

我在这里使用Kernel.SpecialForms.for/1理解:

data = %{{:ok, ["k1", "k2", "k3"]} => {:ok, ["v1", "v2", "v3"]},
         {:ok, ["k21", "k22", "k23"]} => {:ok, ["v21", "v22", "v23"]}}

for {{:ok, keys}, {:ok, values}} <- data, do: Enum.zip(keys, values)
#⇒ [
#   [{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}],
#   [{"k21", "v21"}, {"k22", "v22"}, {"k23", "v23"}]
# ]

可选地,可以构建KeywordMap s

的列表
 for {{:ok, keys}, {:ok, values}} <- data do
   keys
   # NB! If and only keys do not come from user input
   #     Please check the comment below for details
   # |> Enum.map(&String.to_atom/1)
   |> Enum.zip(values)   # keywords
   |> Enum.into(%{})     # maps
 end
 #⇒ [%{k1: "v1", k2: "v2", k3: "v3"},
 #   %{k21: "v21", k22: "v22", k23: "v23"}]