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

Ecto.QueryError: 查询中关键字列表无效问题求助

解决Ecto.QueryError: invalid keyword list in query错误

问题根源

你调用Weather.get_by/1时传入了关键字列表(name: name),但你的get_by/1函数定义是接收单个name值,这导致Repo.get_by/2最终收到的查询条件变成name: [name: 实际传入的名称]——这与name字段的:string类型不匹配,因此触发了无效关键字列表的错误。

修复方案

有两种方式可以修正这个问题:

方案1:调整get_by函数以接收关键字列表

修改get_by函数,让它直接接收查询条件的关键字列表,和Repo.get_by/2的参数风格保持一致:

def get_by(clauses) do
  Weather.Location
  |> Repo.get_by(clauses)
end

这样控制器里的Weather.get_by(name: name)调用就完全正确了,clauses会被直接传递给Repo.get_by/2生成合法的查询。

方案2:调整控制器的调用方式

如果想保持get_by函数只接收单个name参数,那么控制器里的调用需要改成传递原始值,而不是关键字列表:

# 控制器里的fetch函数
def fetch(conn, name) do
  case Weather.get_by(name) do  # 直接传name,而非name: name
    %Weather.Location{} = location ->
      json(conn, Map.take(location, Weather.Location.fields()))

    nil ->
      IO.inspect("Weather not found for '#{name}'")
  end
end

额外需要修正的问题

你的Weather.Location.changeset/2函数里直接调用了Weather.Repo.insert(),这不符合Ecto最佳实践:changeset的职责是生成验证后的变更集,数据库操作(插入/更新)应该单独抽离出来。示例如下:

def changeset(location, params \\ %{}) do
  location
  |> Ecto.Changeset.cast(params, [:name, :temp, :pressure, :humidity, :windspeed, :winddeg])
  # 可添加验证规则,比如确保name不为空
  |> Ecto.Changeset.validate_required([:name])
end

# 单独的插入函数
def create_location(params) do
  %__MODULE__{}
  |> changeset(params)
  |> Weather.Repo.insert()
end

内容的提问来源于stack exchange,提问作者Mouad Bahri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:36:20