Comments (4)
Hey @davidye can you provide more info? Can you show your loader file?
from dataloader.
@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
from dataloader.
@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.
Fixed in #98
from dataloader.
Related Issues (20)
- Discussion about how to handle deeply nested dataloader HOT 3
- Map.t() dialyzer issue HOT 1
- limits or something else? HOT 2
- Accessing values from the context and passing in as argument HOT 1
- Badmatch error when child have limit and offset and parent have composite primary keys HOT 3
- Return response fields based on the context HOT 3
- Redundant ecto queries HOT 2
- New release planned? HOT 4
- Error when used in transactions HOT 16
- run_batch override for association loads HOT 3
- Any change for a newer release with support for Telemetry 1.0? HOT 1
- Dataloader returning invalid key within its resultset HOT 2
- Would it be possible to get a release published? HOT 4
- Confused on KV Operation HOT 1
- Multiple resolutions resulting in duplicate DB calls HOT 1
- Proposal for a high-level declarative Dataloader API
- Proposal for a high-level Ecto dataloader HOT 2
- Customize the association data with a callback similar to `run_batch/5`? HOT 3
- Dataloader queries assoc even if already loaded HOT 1
- Cryptic "bad bug" on patch update HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dataloader.