Elixir Repo.insert_all / 2和唯一约束

时间:2019-05-23 23:23:47

标签: elixir phoenix-framework ecto

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

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

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 

就目前而言,这似乎是 hack 。由于我知道有一个内置的变更集机制,可以处理唯一的约束,但是我不知道如何用Repo.insert_all/3

包含系统的那一部分。

但是,由于insert_all函数并不关心变更集,因此这变得更加困难。

(我当然是指unique_constraint/2

我知道我可以做到

  • 使用Multi执行此操作,但这会在后端创建单独的查询,而不是将其作为一个大查询

  • 使用try rescue块保留代码,但由于模式匹配的原理并使术语崩溃,我想看看是否还有更多的Elixir-y方法可以解决此问题。 / p>

1 个答案:

答案 0 :(得分:4)

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

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

通常情况下,是否要处理冲突,他们确实将该选项设置为有所帮助,而不是引发异常。

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