Elixir Repo.insert_all/2 和唯一约束

dev*_*ium 2 elixir ecto phoenix-framework

我今天遇到了一个相当有趣的问题。我正在尝试使用 Ecto 函数实现从 CSV 文件到我的数据库的批量插入,Repo.insert_all/2但是,有一件事困扰着我。

问题是我的上下文中的以下代码:

defmodule AppName.Roles do
  def bulk_insert(array_of_maps) do
    try do 
      Repo.insert_all(Role, array_of_maps)
    rescue
      exception in Postgrex.Error ->
        _handle_exception(exception) # or whatever
    end
  end
end 
Run Code Online (Sandbox Code Playgroud)

不过就目前而言,这似乎是一个hack。因为我知道有一个内置的变更集机制可以处理独特的约束,但我不知道如何将系统的那部分包含在Repo.insert_all/3

但是由于该insert_all函数不关心变更集,所以这更加困难。

(我当然是指unique_constraint/2

我知道我可以:

  • 使用Multi执行此,但是这创造了在后台单独的查询,而不是做它作为一个大的查询

  • 使用try rescue块保留代码,但我想看看是否有更多 Elixir-y 方法来解决这个问题,因为模式匹配的哲学让它崩溃了术语。

Ale*_*kin 5

Ecto.Repo.insert_all/3 接受选项列表,其中之一是

  • :on_conflict— 它可能是:raise(默认)、:nothing:replace_all:replace_all_except_primary_key{:replace, fields}、 更新指令的关键字列表或更新Ecto.Query查询之一。

通常,无论是否想处理冲突,他们都会将该选项设置为有帮助,而不是引发异常。

:conflict_target可以使用选项来提供不安全的片段