【问题标题】:How can I see the raw SQL generated for an Ecto.Query?如何查看为 Ecto.Query 生成的原始 SQL?
【发布时间】:2020-01-25 19:56:28
【问题描述】:

我有一个Ecto.Query 和一个Repo,这样我就可以调用Repo.all(query) 并获得结果。然而,结果并不是我所期望的。

如何查看Repo 将从Ecto.Query 生成的原始SQL?

【问题讨论】:

    标签: elixir ecto


    【解决方案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", []}
    

    如果您使用的是基于 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]}
    

    【讨论】:

    【解决方案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】:

    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]}
    

    【讨论】:

    • 在 Elixir 1.7.3 上我得到了Repo.to_sql/3 is undefined or private
    • @AlxVallejo 不是Repo.to_sql/3,而是MyApp.Repo.to_sql/2。它应该适用于 Ecto 3 甚至更早的版本
    【解决方案4】:

    基本上是Gazlers 的答案,但修改为在代码中使用:

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

    您可以使用简单的IO.inspect,但它会输出带有反斜杠的查询。

    【讨论】:

    • 我的每个查询关系模型都出现“Ecto.Queryable 未实现”错误。您必须先预加载它们吗?我需要预加载似乎很奇怪。
    猜你喜欢
    • 2023-01-14
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    相关资源
    最近更新 更多