Elixir使用Ecto查询Postgres用户时出现Keyword.merge不存在错误
问题原因
你触发报错的核心是Ecto.Repo.all的参数用法错误:Repo.all的函数签名为Repo.all(queryable, opts \\ []),第一个参数接收查询结构体,第二个参数只能是关键字列表类型的配置项。你当前的代码把两个独立的查询逻辑混传了:管道前半段已经拼了带preload的User查询作为第一个参数,又额外传了一个独立的from u in User查询结构体作为第二个参数,Repo内部会把第二个参数当成配置关键字列表调用Keyword.merge合并默认配置,自然就触发了「参数不是列表类型」的匹配错误。
解决方案
把过滤条件和预加载逻辑合并到同一个查询链即可,可选写法有两种:
- 写法1:把过滤条件放在查询最前面
def get_user_by_email(email) do from(u in User, where: u.email == ^email) |> preload(:exchange_accounts) |> preload(:pos_account) |> Repo.all() end
- 写法2:用管道链式拼接过滤规则
def get_user_by_email(email) do User |> where(email: ^email) |> preload(:exchange_accounts) |> preload(:pos_account) |> Repo.all() end
额外提示:如果邮箱字段是唯一索引,建议把Repo.all()替换为Repo.one(),直接返回单条用户记录而非列表,更符合业务语义。
内容的提问来源于stack exchange,提问作者Sohaib Anwaar
相关产品推荐
相关产品推荐

