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

