Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the simplest way to do upsert with Ecto (MySQL)

Doing upsert is common in my app and I want to implement the cleanest and simple way to implement upsert.

  1. Should I use fragments to implement native sql upsert?
  2. Any idiomatic ecto way to do upsert?
like image 243
Teo Choong Ping Avatar asked Jun 08 '16 07:06

Teo Choong Ping


1 Answers

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
like image 122
Alex Troush Avatar answered Oct 14 '22 09:10

Alex Troush