You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Elixir中测试原生SQL查询无结果的问题求助

在Elixir中测试原生SQL查询无结果的问题求助

我之前也碰到过一模一样的问题,大概率是表名前缀处理或者Ecto Sandbox事务隔离的细节导致的,给你几个实用的排查方向:

1. 确认原生SQL的表名和Ecto实际使用的一致

Ecto默认会给表名加上配置的前缀(比如默认的public),如果你的Inquiry schema设置了@schema_prefix,或者Repo配置里指定了prefix,直接写SELECT * FROM inquiries就会找不到正确的表。

你可以先打印出Ecto实际使用的表信息:

# 在测试里执行,查看真实表名
IO.inspect(Inquiry.__schema__(:source))
# 若有前缀,查看前缀
IO.inspect(Inquiry.__schema__(:prefix))

然后把原生查询改成带正确前缀的版本:

table_name = Inquiry.__schema__(:source)
prefix = Inquiry.__schema__(:prefix) || Repo.config()[:prefix] || "public"
query = "SELECT * FROM #{prefix}.#{table_name}"
results = Ecto.Adapters.SQL.query(Repo, query, [])

2. 验证Ecto Sandbox共享模式是否生效

有时候setup块的配置可能因为测试开启了async: true,或者进程关联问题没生效。你可以试试在测试函数里手动设置模式,或者暂时关闭测试的async:

# 先把测试的async: true改成async: false试试
test "原生SQL查询能获取插入的数据" do
  :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo)
  Ecto.Adapters.SQL.Sandbox.mode(Repo, {:shared, self()})

  Repo.insert!(%Inquiry{<你的字段>})
  
  table_name = Inquiry.__schema__(:source)
  query = "SELECT * FROM #{table_name}"
  {:ok, %{rows: rows}} = Ecto.Adapters.SQL.query(Repo, query, [])
  
  assert length(rows) > 0
end

3. 用Ecto.Query生成SQL做参考

如果还是摸不准问题在哪,可以让Ecto帮你生成正确的SQL,然后照着写原生查询:

# 生成Ecto查询对应的SQL语句
{sql, _params} = Ecto.Query.from(i in Inquiry, select: i) |> Repo.to_sql(:all)
IO.inspect(sql)

把打印出来的SQL直接拿去执行,肯定能得到和Repo.all(Inquiry)一样的结果。

一般来说,表名前缀的问题是最常见的,先排查这个基本就能解决问题~

备注:内容来源于stack exchange,提问作者Brad Pardee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 07:58:07