使用 Ecto.Query 查询具有 UUID 的 table 给出 Ecto.Query.CastError
Querying a table with UUID using Ecto.Query gives 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 一起使用的正确方法,我环顾四周,但有几个人的做法不同。我在 postgrex
.
中使用 Ecto 2.1 和 Postgres 10.0
关于如何让 Ecto 正确查询和转换 UUID 的任何提示?
编辑:我在查询中提供的 ID 是我从数据库中复制的实际现有 ID。
我发现您遇到的问题一开始有点令人困惑,但我认为它工作得很好 - 问题在于您查询数据库的方式。
如果您已准备好查询,则需要使用 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,但实际上,查询不是 cast-able,在异常中解释为:
** (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<>
都包含在 `` 中吗?
您可以在文档中找到更多信息:
希望对您有所帮助!
所以我进行了以下迁移:
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 一起使用的正确方法,我环顾四周,但有几个人的做法不同。我在 postgrex
.
关于如何让 Ecto 正确查询和转换 UUID 的任何提示?
编辑:我在查询中提供的 ID 是我从数据库中复制的实际现有 ID。
我发现您遇到的问题一开始有点令人困惑,但我认为它工作得很好 - 问题在于您查询数据库的方式。
如果您已准备好查询,则需要使用 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,但实际上,查询不是 cast-able,在异常中解释为:
** (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<>
都包含在 `` 中吗?
您可以在文档中找到更多信息:
希望对您有所帮助!