Ecto 3.x下Ecto.DateTime/Ecto.Date.cast()废弃后的代码改造咨询
Ecto 3.x 升级:替换废弃的 Ecto.DateTime 和 Ecto.Date
1. 处理 Ecto.DateTime.cast() 的替换
你的 media.inserted_at 是 NaiveDateTime 类型(即 ~N[2019-01-11 09:55:34] 格式),在 Ecto 3.x 中这种类型本身就是合法的数据库字段类型,完全不需要额外的 cast 转换。原来的代码可以直接简化:
inserted_at = media.inserted_at
如果必须保留 {:ok, ...} 的返回结构(比如原有代码依赖这个模式匹配逻辑),直接返回成功结果即可:
{:ok, inserted_at} = {:ok, media.inserted_at}
如果业务需要将无时区的 NaiveDateTime 转换为带时区的 DateTime,可以用 NaiveDateTime.to_datetime/2 指定时区(以UTC为例):
{:ok, inserted_at} = NaiveDateTime.to_datetime(media.inserted_at, "Etc/UTC")
2. 处理 Ecto.Date.cast() 的替换
Ecto.Date 已被废弃,现在直接使用 Elixir 标准库的 Date 类型即可。结合你用 Timex 解析日期的逻辑,改造后的代码如下:
def parse_media_date(params, key) do case params[key] |> Timex.parse("{YYYY}-{0M}-{0D}") do {:ok, naive_datetime} -> # 若Timex返回的是NaiveDateTime,提取其中的Date部分 date = Date.from_naive!(naive_datetime) %{params | key => date} {:ok, date} when is_struct(date, Date) -> # 若Timex直接返回标准库的Date类型,直接使用即可 %{params | key => date} {:error, _reason} -> params end end
如果想更简洁,可以让 Timex 直接返回 Date 类型:
def parse_media_date(params, key) do case Timex.parse(params[key], "{YYYY}-{0M}-{0D}", :date) do {:ok, date} -> %{params | key => date} {:error, _reason} -> params end end
关键点总结
- 旧的
Ecto.DateTime对应现在的NaiveDateTime(无时区)或DateTime(带时区); - 旧的
Ecto.Date直接替换为 Elixir 标准库的Date; - Ecto 3.x 原生支持标准库的时间/日期类型,无需再通过
Ecto.*.cast做转换,直接使用即可。
内容的提问来源于stack exchange,提问作者tmariaz
相关产品推荐
相关产品推荐

