从 Phoenix/Elixir 中的 CSV 文件播种数据库

Seeding the Database from a CSV file in Phoenix/Elixir

当我尝试 运行: mix run priv/repo/seeds.exs 时,我遇到了问题:(FunctionClauseError) no function clause matching in anonymous fn/1 in :elixir_compiler_1.__FILE__/1 The following arguments were given to anonymous fn/1 in :elixir_compiler_1.__FILE__/1:

这是我的 seeds.exs 文件:

alias FlightsList.Repo
alias FlightsList.Management.Flights

File.stream!("C:/Users/vukap/phx_projects/flights_list/priv/repo/flights.csv")
|> Stream.drop(1)
|> CSV.decode(headers: [:Id, :Origin, :Destination, :DepartureDate, :DepartureTime, :ArrivalDate, :ArrivalTime, :Number])
|> Enum.each(fn {:ok, map} ->
  Flights.changeset(
    %Flights{},
    %{Id: String.to_integer(map[:Id]), Origin: map[:Origin], Destination: map[:Destination], DepartureDate: String.to_integer(map[:DepartureDate]), DepartureTime: String.to_integer(map[:DepartureTime]), ArrivalDate: String.to_integer(map[:ArrivalDate]), ArrivalTime: String.to_integer(map[:ArrivalTime]), Number: map[:Number]})
  |> Repo.insert!()
end)

我该如何解决?

在您指定 CSV 您使用的库之前,或者至少在 The following arguments were given to anonymous fn/1,但问题肯定是 CSV.decode/2 返回的内容不同于 {:ok, map} 您的下一个子句所期望的内容。

要解决此问题和类似问题,可以将包罗万象的子句添加到处理过程中并检查结果。

...
|> Enum.each(fn
  {:ok, map} -> Flights.changeset(...)
  other -> IO.inspect(other, label: "Unexpected")
end)

检查上面会打印出什么并相应地修复它。

我猜你在 CSV.decode 函数中缺少一个 separator,这里是我如何做的一个例子,你可以在种子文件中调用 stream_csv

  def store_it(row) do
    {:ok, result} = row

    %Segments{
      id: result.id,
      name: result.name
    } |> Repo.insert!
  end

  def stream_csv do
    Path.expand("~/Project/segmments.csv")
    |> File.stream!
    |> CSV.decode(separator: ?;, headers: [:id, :name])
    |> Enum.each(&store_it/1)
  end