How to retrieve the sql query from relationships?

Is there some way to retrieve a query from a relationship filter?

I know that for normal read actions I can do something like

MyResource |> Ash.Query.for_read(:my_action, %{}) |> Ash.Query.data_layer_query() |> elem(1) |> then(&Repo.to_sql(:all, &1))

Which works fine most of the times.

But I can’t figure out how to do the same with a relationship load.

Would it be hard to have some helper in Ash to do the same thing that Repo.to_sql does but within Ash so it works all the time and also returns a list of queries in case the action will run more than one (loads, calculations, etc)?

Yes, that would be quite difficult unfortunately. At the moment there is no good helper to get the data layer query for related data, you’ll have to do that manually, i.e filtering the other resource by ids before calling Ash.Query.data_layer_query on it.

If you don´t mind can you give me an example on how to do that? I’m not sure how to retrieve the query of a relationship load.

There is no specific way. You’d need to do something like

OtherResource
|> Ash.Query.filter(<destination_field> in ^list_of_ids)
|> ....

and then you can use data_layer_query to get the equivalent ecto query.

A better question might be why you need this :slight_smile: Often times the need for it can be avoided.

Basically I want to run the query with explain analyze to see what the plan postgres is generating and if it is using my indexes correctly.

My suggestion would be to look at the logs in that case. Ecto logs all queries at debug level, so you could set your log level to debug and see all the queries being run.

Yep, that is what I’m doing as a workaround

This package may help for that kind of thing as well: GitHub - fuelen/ecto_dev_logger: An alternative logger for Ecto queries

1 Like

Thank you so much for that suggestion, that library is amazing! I always hated that in the end the generated sql query would still need manual changes to make it a real query. That library will help a ton!!