What is the simplest way to do upsert with Ecto (MySQL)
In my case insert_or_update
raised an error due to the unique index constraint ð¤
What did work for me was Postgres v9.5 upsert through on_conflict
parameter:
(considering unique column is called user_id
)
changeset
|> MyRepo.insert(
on_conflict: :replace_all,
conflict_target: :user_id
)
You can use Ecto.Repo.insert_or_update/2, please note that for this to work, you will have to load existing models from the database.
model = %Post{id: 'existing_id', ...}
MyRepo.insert_or_update changeset
# => {:error, "id already exists"}
Example:
result =
case MyRepo.get(Post, id) do
nil -> %Post{id: id} # Post not found, we build one
post -> post # Post exists, using it
end
|> Post.changeset(changes)
|> MyRepo.insert_or_update
case result do
{:ok, model} -> # Inserted or updated with success
{:error, changeset} -> # Something went wrong
end