I want to store a Unix timestamp with Ecto in a SQLite database. Unfortunately, I’m getting a changeset validation error when inserting timestamps e.g. 1643408628.
I’m new to Ecto so most likely it’s just some misunderstanding on my side…
Migration:
defmodule TelegramNotes.Repo.Migrations.CreateNotes do
use Ecto.Migration
def change do
create table(:notes) do
add :title, :string
add :body, :text
add :date, :utc_datetime
timestamps()
end
end
end
Schema:
defmodule TelegramNotes.Notes.Note do
use Ecto.Schema
import Ecto.Changeset
schema "notes" do
field :title, :string
field :body, :string
field :date, :utc_datetime
timestamps()
end
@doc false
def changeset(note, attrs) do
note
|> cast(attrs, [:title, :body, :date])
|> validate_required([:title, :date])
end
end
After trying to insert something into the db I’m getting a changeset error:
** (MatchError) no match of right hand side value: {:error, #Ecto.Changeset<action: :insert, changes: %{title: "Hallo!"},
errors: [date: {"is invalid", [type: :utc_datetime, validation: :cast]}], data: #TelegramNotes.Notes.Note<>, valid?: false>}
Hey @r6203, from Ecto’s perspective, 1643408628 is an integer, not a datetime. If you want to convert that integer into a datetime you need to use DateTime — Elixir v1.13.2
Ecto won‘t accept non datetime changes in the first place. The best way to handle integer input is to use a custom ecto type, which converts integer to datetime on cast/1.