Check if record already loaded when running
Closed this issue · 1 comments
I've run into a problem where loading the same item from the same source with the same batch key, but after dataloader has already ran, causes the record to be fetched again. Example:
post(id: 1) {
children {
parentPost { ... }
}
}
In the resolver for the "post" query, I load the record with dataloader instead of just using raw ecto because I want its children to be able to read it without fetching it again. When I run the above query, it runs the SELECT ... FROM posts WHERE id = ANY([1, ...])
. Then it runs the query to get its children and when resolving the parentPost
field, it runs the SELECT ... FROM posts WHERE id = ANY([1, ...])
query again. The example isn't great because it looks like fetching parentPost is unnecessary, but I don't actually have that field, I just need to get the parent to perform some logic on each child post.
Looking at dataloader's code, it looks like when run_batches/1
calls run_batch/2
function (not the customizablerun_batch/5
), run_batch/2
never checks to see if the record has already been loaded, that check only happens in load
dataloader/lib/dataloader/ecto.ex
Line 452 in 532d67e
Is this intended behavhior, or could this be fixed?
EDIT: Opened up the debugger and it looks like the checking in load should be enough, now I just have to figure out why fetched?/3 is returning false
Okay this one was my bad. The id that I used as the item key when I first fetched it was from the arguments on the query which resulted in a string id. The id that I was using later was from an association which gave me an integer id. I used my own IDTranslator that calls String.to_integer/1
on the id and now it works.