Ecto 插入不会自动填充时间戳字段
Ecto insert does not fill timestamp fields automatically
当我尝试使用 Ecto
:
向我的数据库中插入一行时
sla = %MyMetrics.MonthlySLA{metric_name: "x", metric_type: "y", value: 43.33, metric_date: Date.new!(2020,1,1)}
MyMetrics.Repo.insert(sla)
我收到这个错误:
17:44:26.704 [debug] QUERY ERROR db=134.8ms queue=143.8ms idle=1397.2ms
INSERT INTO `monthly_slas` (`metric_date`,`metric_name`,`metric_type`,`value`) VALUES (?,?,?,?) [~D[2020-01-01], "x", "y", #Decimal<43.33>]
** (MyXQL.Error) (1364) (ER_NO_DEFAULT_FOR_FIELD) Field 'inserted_at' doesn't have a default value
(ecto_sql 3.5.3) lib/ecto/adapters/myxql.ex:241: Ecto.Adapters.MyXQL.insert/6
(ecto 3.5.5) lib/ecto/repo/schema.ex:649: Ecto.Repo.Schema.apply/4
(ecto 3.5.5) lib/ecto/repo/schema.ex:262: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
我的 Ecto
模型。
defmodule MyMetrics.MonthlySLA do
use Ecto.Schema
import Ecto.Changeset
schema "monthly_slas" do
field :metric_name, :string
field :metric_type, :string
field :metric_date, :date
field :value, :decimal
end
def changeset(monthly_sla, params \ %{}) do
monthly_sla
|> Ecto.Changeset.cast(params, [:metric_name, :metric_type, :metric_date, :value])
|> Ecto.Changeset.validate_required([:metric_name, :metric_type, :metric_date, :value])
end
end
和我的迁移定义:
defmodule MyMetrics.Repo.Migrations.CreateMonthlySla do
use Ecto.Migration
def change do
create table(:monthly_slas) do
add :metric_name, :string, null: false
add :metric_type, :string, null: false
add :metric_date, :date, null: false
add :value, :decimal, precision: 10, scale: 2, null: false
timestamps()
end
create unique_index(:monthly_slas, [:metric_name, :metric_date])
create unique_index(:monthly_slas, [:metric_date, :metric_name])
create unique_index(:monthly_slas, [:metric_type, :metric_name, :metric_date])
create unique_index(:monthly_slas, [:metric_date, :metric_type, :metric_name])
end
end
如何解决这个问题?
您需要将 timestamps()
添加到您的 Ecto 模型中。您的迁移定义了 inserted_at
和 updated_at
字段的架构,但您的代码需要在将模型插入 table 时提供这些字段。这就是 timestamps()
宏的用途。
defmodule MyMetrics.MonthlySLA do
use Ecto.Schema
import Ecto.Changeset
schema "monthly_slas" do
field :metric_name, :string
field :metric_type, :string
field :metric_date, :date
field :value, :decimal
# Add this
timestamps()
end
def changeset(monthly_sla, params \ %{}) do
monthly_sla
|> Ecto.Changeset.cast(params, [:metric_name, :metric_type, :metric_date, :value])
|> Ecto.Changeset.validate_required([:metric_name, :metric_type, :metric_date, :value])
end
end
当我尝试使用 Ecto
:
sla = %MyMetrics.MonthlySLA{metric_name: "x", metric_type: "y", value: 43.33, metric_date: Date.new!(2020,1,1)}
MyMetrics.Repo.insert(sla)
我收到这个错误:
17:44:26.704 [debug] QUERY ERROR db=134.8ms queue=143.8ms idle=1397.2ms
INSERT INTO `monthly_slas` (`metric_date`,`metric_name`,`metric_type`,`value`) VALUES (?,?,?,?) [~D[2020-01-01], "x", "y", #Decimal<43.33>]
** (MyXQL.Error) (1364) (ER_NO_DEFAULT_FOR_FIELD) Field 'inserted_at' doesn't have a default value
(ecto_sql 3.5.3) lib/ecto/adapters/myxql.ex:241: Ecto.Adapters.MyXQL.insert/6
(ecto 3.5.5) lib/ecto/repo/schema.ex:649: Ecto.Repo.Schema.apply/4
(ecto 3.5.5) lib/ecto/repo/schema.ex:262: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
我的 Ecto
模型。
defmodule MyMetrics.MonthlySLA do
use Ecto.Schema
import Ecto.Changeset
schema "monthly_slas" do
field :metric_name, :string
field :metric_type, :string
field :metric_date, :date
field :value, :decimal
end
def changeset(monthly_sla, params \ %{}) do
monthly_sla
|> Ecto.Changeset.cast(params, [:metric_name, :metric_type, :metric_date, :value])
|> Ecto.Changeset.validate_required([:metric_name, :metric_type, :metric_date, :value])
end
end
和我的迁移定义:
defmodule MyMetrics.Repo.Migrations.CreateMonthlySla do
use Ecto.Migration
def change do
create table(:monthly_slas) do
add :metric_name, :string, null: false
add :metric_type, :string, null: false
add :metric_date, :date, null: false
add :value, :decimal, precision: 10, scale: 2, null: false
timestamps()
end
create unique_index(:monthly_slas, [:metric_name, :metric_date])
create unique_index(:monthly_slas, [:metric_date, :metric_name])
create unique_index(:monthly_slas, [:metric_type, :metric_name, :metric_date])
create unique_index(:monthly_slas, [:metric_date, :metric_type, :metric_name])
end
end
如何解决这个问题?
您需要将 timestamps()
添加到您的 Ecto 模型中。您的迁移定义了 inserted_at
和 updated_at
字段的架构,但您的代码需要在将模型插入 table 时提供这些字段。这就是 timestamps()
宏的用途。
defmodule MyMetrics.MonthlySLA do
use Ecto.Schema
import Ecto.Changeset
schema "monthly_slas" do
field :metric_name, :string
field :metric_type, :string
field :metric_date, :date
field :value, :decimal
# Add this
timestamps()
end
def changeset(monthly_sla, params \ %{}) do
monthly_sla
|> Ecto.Changeset.cast(params, [:metric_name, :metric_type, :metric_date, :value])
|> Ecto.Changeset.validate_required([:metric_name, :metric_type, :metric_date, :value])
end
end