insert_all does not create auto generated inserted_at with ecto 2.0
Asked Answered
C

2

10
# 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
Corpulent answered 31/5, 2016 at 4:54 Comment(0)
A
18

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).

Acrostic answered 31/5, 2016 at 7:29 Comment(3)
Thank you. Got error for updated_at now. Fixed it with the one suggested above.Corpulent
the :datetime type in migrations is deprecated, please use :utc_datetime or :naive_datetime insteadHackneyed
Ecto.DateTime seems deprecated, DateTime.utc_now() works for me.Lully
H
1

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 of insert/2 ..

Houseyhousey answered 20/10, 2017 at 7:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.