flp
Multi.insert_all/Repo.insert_all fail with Enumerable not implemented
I tried to use the insert_all functions to batch insert 2 records, but it always fails with Enumerable not implemented for Model:
Repo.insert_all(Model, [%Model{id: 1, friend_id: 4}, %Model{id: 4, friend_id: 1}])
I got it working by inserting every record at once:
Multi.new
|> Multi.insert(:model1, %Model{id: 1, friend_id: 4})
|> Multi.insert(:model2, %Model{id: 4, friend_id: 1})
|> Repo.transaction
Maybe my misunderstanding is that only normal maps are supported?
Repo.insert_all(Model, [%{id: 1, friend_id: 4}, %{id: 4, friend_id: 1}])
Unfortunately, then the timestamp values are not automatically set:
null value in column "inserted_at" violates not-null constraint
Is there any way to achieve the batch insertion with phoenix models and what exactly is my mistake or misunderstanding?
Most Liked
kylethebaker
It looks like only lists of maps or keyword lists are supported. From the @spec:
entries :: [map | Keyword.t]
There is some explanation in the documentation about why this is the case:
However any other autogenerated value, like timestamps, won’t be autogenerated when using insert_all/3. This is by design as this function aims to be a more direct way to insert data into the database without the conveniences of insert/2. This is also consistent with update_all/3 that does not handle timestamps as well.
It is also not possible to use insert_all to insert across multiple tables, therefore associations are not supported.
It does feel like a shortcoming though, I’m not sure why it doesn’t work with schemas/structs.
EDIT: You could create a utility around Multi like this:
def insert_multiple(entries) do
multi =
Enum.reduce entries, Multi.new(), fn(multi, entry) ->
Multi.insert(multi, entry.id, entry)
end
Repo.transaction(multi)
end
It depends on the struct to have an id field for the multi name, but you could change that to anything I think, it just needs to be unique.
idi527
You can insert your data with timestamps like so
to_insert =
[%{id: 1, friend_id: 4}, %{id: 4, friend_id: 1}]
|> Enum.map(&Map.put(&1, :inserted_at, NaiveDateTime.utc_now()))
Repo.insert_all(Model, to_insert)







