Как я могу увидеть исходный SQL, сгенерированный для Ecto.Query?

У меня есть Ecto.Query и a Repo, поэтому я могу вызвать Repo.all(query) и получить результаты. Однако результаты не то, что я ожидаю.

Как я могу увидеть исходный SQL, который Repo будет генерировать из Ecto.Query?

Ответ 1

Вы можете использовать Ecto.Adapters.SQL.to_sql/3:

iex> Ecto.Adapters.SQL.to_sql(:all, Repo, Post)
{"SELECT p.id, p.title, p.inserted_at, p.created_at FROM posts as p", []}

Запрос может представлять собой любую структуру, которая реализует протокол Ecto.Queryable, например Post (который является модулем, который импортирует Ecto.Schema). Также можно передать Ecto.Query:

iex> query = Ecto.Query.where(Post, [p], p.views > 10)
iex> Ecto.Adapters.SQL.to_sql(:all, Repo, query)
{"SELECT p.id, p.title, p.inserted_at, p.created_at FROM posts as p WHERE p.views > $1", [10]}

Ответ 2

Удобный вспомогательный метод для печати необработанного SQL

def print_sql(queryable) do
  IO.inspect(Ecto.Adapters.SQL.to_sql(:all, Repo, queryable))
  queryable
end

def list_new_foos() do
  Foo
  |> where([foo], foo.bar == 1337)
  |> limit(100)
  |> print_sql
  |> Repo.all()
end

Ответ 3

Это в основном ответ Gazler, но модифицированный для использования в коде:

query = from p in Post
{query, params} = Ecto.Adapters.SQL.to_sql(:all, Repo, query)
IO.puts("#{query}, #{inspect(params)}")

Вы можете использовать простой IO.inspect, но он выведет запрос с обратной косой чертой.

Ответ 4

to_sql/2 добавлен к модулю, на котором вы use Ecto.Repo. По соглашению этот модуль будет называться MyApp.Repo (MyApp будет именем вашего приложения). Внутренне он будет использовать Ecto.Adapters.SQL.to_sql/3, но Ecto.Adapters.SQL - это скорее внутренний модуль.

Использование будет выглядеть следующим образом:

iex> query = Ecto.Query.where(Post, [p], p.views > 10)
iex> MyApp.Repo.to_sql(:all, query)
{"SELECT p.id, p.title, p.inserted_at, p.created_at FROM posts as p WHERE p.views > $1", [10]}