Reputation: 1729
# mix.exs
defp deps do
[{:phoenix, "~> 1.1.4"},
{:postgrex, ">= 0.0.0"},
{:phoenix_ecto, "~> 3.0.0-rc"},
{:gettext, "~> 0.9"},
...
]
end
The installed ecto version is "2.0.0-rc.5"
iex(1)> categories = [%{name: "stackoverflow", url: "stackoverflow.com"}]
iex(2)> App.Repo.insert_all App.Category, categories
** (Postgrex.Error) ERROR (not_null_violation): null value in column "inserted_at" violates not-null constraint
table: categories
column: inserted_at
Failing row contains (1, stackoverflow, stackoverflow.com, null, null).
(ecto) lib/ecto/adapters/sql.ex:176: Ecto.Adapters.SQL.query!/5
(ecto) lib/ecto/adapters/sql.ex:350: Ecto.Adapters.SQL.insert_all/8
(ecto) lib/ecto/repo/schema.ex:42: Ecto.Repo.Schema.do_insert_all/6
iex(2)>
From the docs, it seemed the inserted_at
was autogenerated. Should I've to manually do this part?
schema "categories" do
field :name, :string
field :url, :string
timestamps
end
Upvotes: 10
Views: 5603
Reputation: 84150
The Ecto.Schema.timestamps/1 function defines the inserted_at
and updated_at
columns. There is a function with the same name in the migrations.
You can either set this at the database level by using:
alter table(:categories) do
modify :inserted_at, :utc_datetime, default: fragment("NOW()")
end
Or you can set it in your map:
categories = [%{name: "stackoverflow", url: "stackoverflow.com", inserted_at: Ecto.DateTime.utc}]
Whichever solution you pick, you will likely have to do the same for updated_at
.
If you don't want to track the timestamps then you can remove timestamps
from your schema and drop the columns in a migration (or if you have not committed the migration to version control, just delete the timestamps
function).
Upvotes: 18
Reputation: 852
From the insert_all documentation:
... timestamps, won’t be autogenerated when using
insert_all/3
. This is by design as this function aims to be a more direct way to insert data into the database without the conveniences ofinsert/2
..
Upvotes: 1