Code Monkey home page Code Monkey logo

Comments (4)

benwilson512 avatar benwilson512 commented on August 10, 2024

Hey @davidye can you provide more info? Can you show your loader file?

from dataloader.

davidye avatar davidye commented on August 10, 2024

@benwilson512 I have schemas User and and UserProfile and querying for user, I preload UserProfile.

So in my resolver:

  def add_source(loader, session) do
    loader
    |> Dataloader.add_source(
      Accounts,
      Dataloader.Ecto.new(
        Repo,
        query: fn _query, params ->
          {_params_session, args} = Map.split(params, [:session])
          Accounts.query(args, session)
        end,
        default_params: %{session: session}
      )
    )
  end

  def user_profile(%User{id: user_id}, _args, %{context: %{loader: loader}}, fun \\ nil) do
    loader
    |> Dataloader.load(Accounts, {User, load: :profile}, user_id)
    |> on_load(fn loader ->
      loader
      |> Dataloader.get(Accounts, {User, load: :profile}, user_id)
      |> case do
        %User{} = user -> {:ok, user.profile}
        nil -> {:error, :not_found}
      end
      |> default_fun(fun)
    end)
  end

So dataloader calls Accounts.query(...) with [load: :profile] and that constructs a standard Ecto query of this form:

    from user in query,
      join: profile in assoc(user, :profile),
      preload: [profile: profile]

Also just noticed there's more error output - did something change with the way dataloader constructs ecto queries in 1.0.8?

11:11:29.346 [error] Task #PID<0.3055.0> started from #PID<0.3058.0> terminating
** (Ecto.SubQueryError) the following exception happened when compiling a subquery.

    ** (Ecto.QueryError) cannot preload associations in subquery in query:

    from u0 in Server.Accounts.User,
      join: u1 in Server.Accounts.UserProfile,
      on: u1.user_id == u0.id,
      where: u0.id == parent_as(:input).id,
      limit: ^40,
      offset: ^0,
      preload: [profile: u1]


The subquery originated from the following query:

from u0 in subquery(from u0 in Server.Accounts.User,
  where: u0.id in ^["18dd4bf9-92ff-4448-9631-b6031355ce32"],
  distinct: true,
  select: [:id]),
  as: :input,
  join_lateral: u1 in subquery(from u0 in Server.Accounts.User,
  join: p1 in assoc(u0, :profile),
  where: u0.id == parent_as(:input).id,
  limit: ^40,
  offset: ^0,
  preload: [profile: p1]),
  on: true,
  select: u1

EDIT: Looks like there's been some changes to preload behavior in lib/dataloader/ecto.ex which maybe related? @mbuhot

https://github.com/absinthe-graphql/dataloader/commits/6cd72f263563f49dc31cd351234241cce0c4a0ef/lib/dataloader/ecto.ex

from dataloader.

mbuhot avatar mbuhot commented on August 10, 2024

@davidye yes the presence of the limit/offset in the query is causing it to use a new code path that runs your query as a lateral subquery.
It's intended to support getting the first N associated rows per parent record, but looks like I didn't test it with preloads, 🤦‍♂️.

To fix this specific issue we could update the code to not use the load_rows_lateral function when loading a batch of rows using the primary key. load_rows_lateral should only be used when loading an association by a foreign key.

I'll have to do some experimenting to figure out how to support preloads generally.
In some cases we could replace a preload in the subquery with a preload in the outer query, or a call to Repo.preload However that won't work for join preloads 🤔

from dataloader.

benwilson512 avatar benwilson512 commented on August 10, 2024

Fixed in #98

from dataloader.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.