pau-riosa

pau-riosa

What could be the best way to fetch large data from database? Is it using Stream.resource or Repo.stream and Repo.transaction?

I am planning to read large data from a database for a report, what could be the best way of getting these reports? Is it via Stream.resource where I could set a limit and offset or Repo.stream inside a Repo.transaction?

Marked As Solved

dimitarvp

dimitarvp

Repo.stream has never failed me. Use that.

You could also fetch with a key to control pagination i.e. values of the primary key.

Also Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Repo.stream is great, but sometimes you need to process hundreds of thousand to millions of records over minutes of time, and the issues of doing that in a single transaction are too great. For that we have this function in our Repo module:

  @doc """
  An alternative to Repo.stream that does not require a transaction.

  On the upside, this allows you to iterate through large collections that may require processing longer
  than is convenient / safe for a single transaction. The target use case here is background jobs
  that periodically comb through large tables and do various updates and interdependent transactions
  aren't relevant.

  The caveat of course is that you aren't operating on a single snapshot of the collection. The way this works
  is that the first N records are fetched, sorted by `asc: :id`. Then the next N records are fetched where
  the id is greater than the biggest id fetched previously.
  """
  def dirty_stream(queryable, opts \\ []) do
    import Ecto.Query

    # TODO: Raise if `queryable` has an `order_by` as we need to override that
    # TODO: Raise if `queryable` has a limit since we also need to override that.

    i = opts[:start_id] || -1
    batch_size = opts[:batch_size] || 100
    mapper = opts[:mapper] || fn record -> record.id end

    Stream.unfold(i, fn i ->
      queryable
      |> where([q], q.id > ^i)
      |> limit(^batch_size)
      |> order_by(asc: :id)
      |> __MODULE__.all()
      |> case do
        [] ->
          nil

        records ->
          new_max_id = records |> List.last() |> mapper.()
          {records, new_max_id}
      end
    end)
    |> Stream.flat_map(& &1)
  end

This is particularly handy when you need to bulk process stuff with preloads since you get a lot of economies of scale, but you can still deal with each record at a time.

pau-riosa

pau-riosa

Thank you

pau-riosa

pau-riosa

Thank you for this one Ben.

Where Next?

Popular in Questions Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New

Other popular topics Top

New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39467 209
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement