Seeding the Database from a CSV file in Phoenix/Elixir

Viewed 205

When I try to run: mix run priv/repo/seeds.exs, I have a problem: (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:

This is my seeds.exs file:

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)

How can I fix it?

2 Answers

It’s impossible to answer precisely until you have specified CSV library you used, or at least what the error actually says after The following arguments were given to anonymous fn/1, but the issue is definitely with CSV.decode/2 returning something different from {:ok, map} your next clause expects.

To fix this and similar issues, one would add the catch-all clause to the processing and examine the outcome.

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

Check what the above would print out and fix it accordingly.

I guess you are missing a separator in CSV.decode function, here is an example of how I do it, you can call stream_csv in seed file.

  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
Related