我有一个
如何查看
Ecto.Query
和一个Repo
,我可以调用Repo.all(query)
获取结果。但是,结果并不是我所期望的。如何查看
Repo
将从 Ecto.Query
生成的原始SQL?iex> Ecto.Adapters.SQL.to_sql(:all, Repo, Post)
{"SELECT p.id, p.title, p.inserted_at, p.created_at FROM posts as p", []}
如果您正在使用基于 SQL 的适配器,该函数也可以在具有名称 to_sql
的存储库下使用:
iex> Repo.to_sql(:all, 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]}
一个方便的辅助方法,用于打印原始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
to_sql/2
被添加到了你所使用的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]}
Repo.to_sql/3 未定义或私有
的错误。 - AlxVallejoRepo.to_sql/3
,而是MyApp.Repo.to_sql/2
。它应该可以与Ecto 3甚至更早的版本一起使用。 - Gjaldon这基本上是 Gazler
的回答,但修改为可在代码中使用:
query = from p in Post
{query, params} = Ecto.Adapters.SQL.to_sql(:all, Repo, query)
IO.puts("#{query}, #{inspect(params)}")
您可以使用简单的IO.inspect
,但它会输出带有反斜杠的查询。
query
结构体代替Post
。 - Nathan LongEcto.Schema
的东西。我会更新我的回答。 - Gazler