在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
相关产品推荐
相关产品推荐

