insert_all не создает автоматически созданный insert_at с ecto 2.0

# mix.exs
  defp deps do
    [{:phoenix, "~> 1.1.4"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_ecto, "~> 3.0.0-rc"},
      {:gettext, "~> 0.9"},
      ...
    ]
  end

Установленная версия экто "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)> 

Судя по документам, inserted_at был сгенерирован автоматически. Должен ли я вручную сделать эту часть?

schema "categories" do
 field :name, :string
 field :url, :string

 timestamps
end

person Vysakh Sreenivasan    schedule 31.05.2016    source источник


Ответы (2)


Ecto.Schema.timestamps/1 определяет столбцы inserted_at и updated_at. В миграции есть функция с таким же названием.

Вы можете установить это на уровне базы данных, используя:

alter table(:categories) do
  modify :inserted_at, :utc_datetime, default: fragment("NOW()")
end

Или вы можете установить его на своей карте:

categories = [%{name: "stackoverflow", url: "stackoverflow.com", inserted_at: Ecto.DateTime.utc}]

Какое бы решение вы ни выбрали, вам, вероятно, придется сделать то же самое для updated_at.

Если вы не хотите отслеживать временные метки, вы можете удалить timestamps из своей схемы и удалить столбцы при миграции (или, если вы не зафиксировали миграцию в системе управления версиями, просто удалите функцию timestamps).

person Gazler    schedule 31.05.2016
comment
Спасибо. Получил ошибку для updated_at сейчас. Исправил предложенным выше. - person Vysakh Sreenivasan; 31.05.2016
comment
тип :datetime в миграциях устарел, используйте вместо него :utc_datetime или :naive_datetime - person arcseldon; 20.01.2018

Из insert_all документации:

... временные метки не будут генерироваться автоматически при использовании insert_all/3. Это задумано, поскольку эта функция предназначена для более прямого способа вставки данных в базу данных без удобств insert/2 ..

person ivanxuu    schedule 20.10.2017