2017-10-17 27 views
0

所以我有以下遷移:查詢使用Ecto.Query UUID表給出了Ecto.Query.CastError

create table(:things, primary_key: false) do 
    add :id, :uuid, primary_key: true 
    add :state, :string 

    timestamps() 
end 

它具有以下模式:

@primary_key {:id, Ecto.UUID, autogenerate: true} 
@derive {Phoenix.Param, key: :id} 
schema "things" do 
    field :state, :string 

    timestamps() 
end 

而且在努力在REPL下面的查詢,我得到一個Ecto.Query.CastError

iex(8)> q = from s in Thing, where: s.id == "ba34d9a0-889f-4999-ac23-f04c7183f2ba", select: s 
#Ecto.Query<from o in App.Thing, 
where: o.id == "ba34d9a0-889f-4999-ac23-f04c7183f2ba", select: o> 
iex(9)> Repo.get!(Thing, q) 
** (Ecto.Query.CastError) /project/deps/ecto/lib/ecto/repo/queryable.ex:341: value `#Ecto.Query<from o in App.Thing, where: o.id == "ba34d9a0-889f-4999-ac23-f04c7183f2ba", select: o>` in `where` cannot be cast to type Ecto.UUID in query: 

from o in App.Thing, 
    where: o.id == ^#Ecto.Query<from o in App.Thing, where: o.id == "ba34d9a0-889f-4999-ac23-f04c7183f2ba", select: o>, 
    select: o 

    (elixir) lib/enum.ex:1811: Enum."-reduce/3-lists^foldl/2-0-"/3 
    (elixir) lib/enum.ex:1357: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3 
    (elixir) lib/enum.ex:1811: Enum."-reduce/3-lists^foldl/2-0-"/3 
    (ecto) lib/ecto/repo/queryable.ex:124: Ecto.Repo.Queryable.execute/5 
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4 
    (ecto) lib/ecto/repo/queryable.ex:78: Ecto.Repo.Queryable.one!/4 
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6 
    (iex) lib/iex/evaluator.ex:219: IEx.Evaluator.handle_eval/5 
    (iex) lib/iex/evaluator.ex:200: IEx.Evaluator.do_eval/3 
    (iex) lib/iex/evaluator.ex:178: IEx.Evaluator.eval/3 

我不知道這是正確的方式使用UUID和Ecto,我環顧四周,但有幾個人以不同的方式做。我正在使用Ecto 2.1和Postgres 10.0以及postgrex

有關如何正確查詢Ecto並轉換UUID的任何提示?

編輯:我在查詢中給出的ID是從數據庫中複製的實際現有ID。

回答

1

我發現你遇到的問題起初有點令人困惑,但我認爲它工作得相當正確 - 問題在於你如何查詢數據庫。

如果你有你的查詢準備好了,你需要使用Repo.all(query),所以你的代碼應該是:

q = from s in Thing, where: s.id == "ba34d9a0-889f-4999-ac23-f04c7183f2ba", select: s 
Repo.all(q) 

您可以查詢數據庫來尋找按主鍵特定的記錄,這是當你可以使用Repo.get!/3

試試這個:

Repo.get!(Thing, "ba34d9a0-889f-4999-ac23-f04c7183f2ba") 

當你通過q作爲第二個參數get!,它會嘗試將其轉換爲UUID,但實際上,查詢不鑄能夠,這是

** (Ecto.Query.CastError) /project/deps/ecto/lib/ecto/repo/queryable.ex:341: value `#Ecto.Query<from o in App.Thing, where: o.id == "ba34d9a0-889f-4999-ac23-f04c7183f2ba", select: o>` in `where` cannot be cast to type Ecto.UUID in query: 

你可以看到整個#Ecto.Query<>被封閉在``:在異常解釋呢?

你可以找到更多的文檔中:

希望幫助!

+0

你是絕對正確的,這是非常明顯的。我受到了以下文檔的偏離:get(queryable :: Ecto.Queryable.t,id :: term,opts :: Keyword.t):: Ecto.Schema.t 而在我的腦海裏,一個Ecto.Queryable .t是一個查詢。 謝謝! –