无法在查询中转换为类型 :naive_datetime

Cannot be cast to type :naive_datetime in query

我有疑问:

 PhoenixApp.one(from r in PhoenixApp.Reply,
              where: r.inserted_at > ^datatime,
              select: count(r.id))

此查询失败并出现错误:value '#Ecto.DateTime<2016-12-04 20:11:21>' in 'where' cannot be cast to type :naive_datetime in query:

但是当使用 type(^datatime, Ecto.DateTime) 转换数据时间时,它是有效的。

问题:为什么会这样,看起来数据时间最初有 DateTime 类型?

使用新的 Ecto 2.1.2

看起来 Ecto 不支持从已弃用的 Ecto.DateTime 转换为新的 Elixir NaiveDateTime 结构,您在 Ecto 2.1+ 中使用 :naive_datetime 时正在使用该结构:

iex(1)> dt = Ecto.DateTime.utc
#Ecto.DateTime<2017-01-08 12:11:59>
iex(2)> Ecto.Type.cast :naive_datetime, dt
:error

Ecto 2.1 中推荐的方法是停止使用已弃用的 Ecto.DateTime 结构并在所有地方使用 Elixir 的新 NaiveDateTime(或 DateTime)。如果您仍想在它们之间进行显式转换,可以执行 |> Ecto.DateTime.to_erl |> NaiveDateTime.from_erl! 并在查询中使用该值:

iex(1)> dt = Ecto.DateTime.utc
#Ecto.DateTime<2017-01-08 12:13:50>
iex(2)> dt |> Ecto.DateTime.to_erl |> NaiveDateTime.from_erl!
~N[2017-01-08 12:13:50]

如果您从 Ecto 查询中获取旧结构,您可能在模式中为它们定义了旧类型,您应该将其从 field :foo, Ecto.DateTime 更改为 field :foo, NaiveDateTime(或 field :foo, DateTime).

另请参阅:https://github.com/elixir-ecto/ecto/blob/v2.1/CHANGELOG.md#integration-with-elixir-13-calendar-types