我今天遇到了一个相当有趣的问题。我正在尝试使用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>
答案 0 :(得分:4)
Ecto.Repo.insert_all/3
接受选项列表,其中一个是
:on_conflict
—可能是:raise
(默认值),:nothing
,:replace_all
,:replace_all_except_primary_key
,{:replace, fields}
,关键字之一更新说明列表或Ecto.Query
查询更新。
通常情况下,是否要处理冲突,他们确实将该选项设置为有所帮助,而不是引发异常。
还可以使用:conflict_target
选项来提供不安全的片段。