ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Ecto.Multi
    기술 동향 2020. 10. 6. 14:21

    Ecto.Multi는 여러 Repo 작업을 그룹화하기위한 데이터 구조입니다.

     

    Ecto.Multi은 가능한 하나의 데이터베이스 트랜잭션에서 수행하고 각 insert/update/delete등의 각 작업은 호출 시, 실행되지 않은 채로 MapSet에서 관리 되어야 합니다. 각 작업은 고유한 key를 가지며 성공 또는 실패의 경우에 그 결과를 식별하는 이름이 지정됩니다.

     

    모든 작업은 추가 된 순서대로 실행됩니다.

     

    %Ecto.Multi{}를 사용하여 유형 일치를 패턴화할 수 있지만 필드에 액세스하거나 직접 수정하는 것은 권장되지 않습니다.

    Ecto.Multi.to_list / 1 내부 검사에 사용할 수있는 구조의 표준 표현을 반환합니다.

     

          pills_attrs
          |> Stream.map(fn pill ->
            change_pill(prescription, pill)
          end)
          |> Stream.map(fn pill_changeset ->
            key = "pill:#{pill_changeset.changes.name}"
            Ecto.Multi.insert(Ecto.Multi.new(), key, pill_changeset)
          end)
          |> Enum.reduce(Ecto.Multi.new(), &Ecto.Multi.append/2)
          |> Repo.transaction()
          |> case do
            {:ok, _pill} -> {:ok, prescription}
            {:error, _failed_operation, failed_value, _changes_so_far} -> {:error, failed_value}
          end

    Ecto.Multi 는 MapSet<>의 구현체입니다.

    여러 개의 Multi를 만들어서 append 또는 prepend 하여 Repo.transaction/1 으로 한 번에 처리할 때 사용합니다.

    Stream.map/3 등을 사용하여 Ecto.Multi를 manipulate하여 사용합니다.

     

     

    혹시 이전 쿼리의 리턴 값이 다음 쿼리에 필요한 경우에는 다음과 같이 처리합니다.

    Ecto.Multi.new()
        |> Ecto.Multi.insert(:insert_prescription, changes_prescription(user, doctor, prescription_attrs))
        |> Ecto.Multi.run(:insert_pills, fn _repo, %{insert_prescription: prescription} ->
    
    		......
    
        |> Repo.transaction()
        |> case do
          {:ok, prescription} -> {:ok, prescription.insert_prescription}
          {:error, _failed_operation, failed_value, _changes_so_far} -> {:error, failed_value}
        end
        
        # prescription.insert_prescription로 빼낸 것을 주목하세요 ^^

     

    Ecto.Multi.run/3 함수를 사용하면 이전 쿼리의 결과 값을 name key로 받아올 수 있습니다.

     

    Ecto.Multi는 transaction이므로 한 번에 많은 데이터를 여러 쿼리를 사용해서 관리할 때 편합니다.

    명시적으로 rollback함수를 호출할 수도 있습니다.

     

    insert_all을 사용할 수도 있지만 이 경우에는 timestampt() 로 생성한 updated_at / created_at을 처리해 주지 않습니다.

    '기술 동향' 카테고리의 다른 글

    Process Register  (0) 2021.04.05
    Ecto Composable Query  (0) 2020.11.16
    History of Erlang  (0) 2020.06.25
    Raft Consensus Algorithm  (0) 2020.06.25
    Elixir Technical Advantages  (0) 2020.06.08

    댓글

Elixian