Эликсир Repo.insert_all / 2 и уникальное ограничение - PullRequest
1 голос
/ 24 мая 2019

У меня сегодня довольно интересная проблема.Я пытаюсь внедрить массовую вставку из файла CSV в мою базу данных, используя функцию Ecto 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 

Пока что это похоже на хак .Поскольку я знаю, что есть встроенный механизм наборов изменений, который обрабатывает уникальные ограничения, но я не знаю, как включить эту часть системы с Repo.insert_all/3

Но поскольку функция insert_all незабота о изменениях это делает это еще сложнее.

(я, конечно, имею в виду unique_constraint/2)

Я знаю, что могу:

  • Используйте Multi для выполнения этого, но это создает отдельных запросов на бэкэнде вместо того, чтобы делать это как один большой запрос

  • Сохраняйте код, используя блок try rescue, но я хотел бы посмотреть, есть ли еще один способ решения этой проблемы с помощью Elixir-y из-за философии сопоставления с образцом, и пусть он терпит крах терминологии.

1 Ответ

4 голосов
/ 24 мая 2019

Ecto.Repo.insert_all/3 принимает список параметров, один из которых

  • :on_conflict - Это может быть один из :raise (по умолчанию), :nothing, :replace_all, :replace_all_except_primary_key, {:replace, fields}, список ключевых слов инструкций по обновлению или Ecto.Query запрос на обновления.

Обычно, если кто-то хочет обрабатывать конфликты, они устанавливают эту опцию несколько полезной вместо того, чтобы вызывать исключение.

Также можно использовать опцию :conflict_target для предоставления небезопасных фрагментов .

...