为什么我得到Ecto.ConstraintError?

时间:2017-08-24 08:34:41

标签: phoenix-framework ecto

虽然我在变更集中将unique_constraint / 3称为:

  def changeset(parent, params \\ %{}) do
    parent
    |> cast(params, [:created_at , :parent_type , :mobile_number])
    |> unique_constraint(:mobile_number, name: :parents_mobile_number_uindex)

  end

当我Repo.update!Repo.update时,我仍然会收到错误:

** (exit) an exception was raised:
    ** (Ecto.ConstraintError) constraint error when attempting to update struct:

    * unique: parents_mobile_number_uindex

If you would like to convert this constraint into an error, please
call unique_constraint/3 in your changeset and define the proper
constraint name. The changeset has not defined any constraint.

        (ecto) lib/ecto/repo/schema.ex:493: anonymous fn/4 in Ecto.Repo.Schema.constraints_to_errors/3
        (elixir) lib/enum.ex:1229: Enum."-map/2-lists^map/1-0-"/2
        (ecto) lib/ecto/repo/schema.ex:479: Ecto.Repo.Schema.constraints_to_errors/3
        (ecto) lib/ecto/repo/schema.ex:284: anonymous fn/13 in Ecto.Repo.Schema.do_update/4
        (ecto) lib/ecto/repo/schema.ex:142: Ecto.Repo.Schema.update!/4
        (myapp) web/controllers/csvs_controller.ex:484: Myapp.CsvsController.parent_insert_or_update/2
        (myapp) web/controllers/csvs_controller.ex:266: anonymous fn/6 in Myapp.CsvsController.write_ecto_rows_schools/6
        (myapp) web/controllers/csvs_controller.ex:219: Myapp.CsvsController.write_ecto_rows_schools/6
        (elixir) lib/task/supervised.ex:85: Task.Supervised.do_apply/2
        (elixir) lib/task/supervised.ex:36: Task.Supervised.reply/5
        (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

有什么想法吗?

编辑:

我已经在DB中有了约束: enter image description here

EDIT2: enter image description here

1 个答案:

答案 0 :(得分:0)

Ecto.ConstraintError 很可能是由于基于您的错误消息的不正确的约束名称而发生的。 “变更集未定义任何约束。”

您将显式索引名称传递给unique_constraint。因此,ecto将寻找唯一索引“parents_mobile_number_uindex”

create unique_index(:parents, [:mobile_number])
# geneated a unique index "parents_mobile_number_index"

要看两件事:

  1. 确保唯一索引名称正确无误:

    ## at your migration file
    create unique_index(:parents, [:mobile_number], name: : parents_mobile_number_uindex)
    
    ## at your schema module.
    def changeset(parent, params \\ %{}) do
        parent
        |> cast(params, [:created_at , :parent_type , :mobile_number])
        |> unique_constraint(:mobile_number, name: : parents_mobile_number_uindex)
    end
    
  2. 确保您确实调用了unique_constraint / 3函数:

    parent |> Parent.changeset(%{mobile_number: parent_model.mobile_number}) |> Repo.update()
    # or
    parent |> Ecto.Changeset.change(mobile_number: parent_model.mobile_number) |> unique_constraint(:mobile_number, name: :parents_mobile_number_uindex) |> Repo.update()