postgresql pkey上的外部唯一约束错误

jxct1oxe  于 2023-02-04  发布在  PostgreSQL
关注(0)|答案(3)|浏览(183)

我在尝试插入新聊天室时开始收到以下错误

** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * unique: rooms_pkey

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 defined the following constraints:

    * unique: rooms_name_index

主键不应该自动递增吗?是什么原因导致这个错误突然发生?插入是作为multi的一部分完成的,相关部分是:

|> Multi.insert(:room, Room.changeset(%Room{}, %{name: "service-user-care-team:" <> Integer.to_string(user.id)}))

为了便于参考,下面是我的模式,其中包括变更集

schema "rooms" do
  field :name, :string
  many_to_many :users, App.User, join_through: "user_rooms", on_delete: :delete_all
  has_many :messages, App.Message

  timestamps()
end

def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:name])
  |> validate_required([:name])
  |> unique_constraint(:name)
end

这是迁移

defmodule App.Repo.Migrations.CreateRoom do
  use Ecto.Migration

  def change do
    create table(:rooms) do
      add :name, :string, null: false

      timestamps()
    end

    create unique_index(:rooms, [:name])
 end
end
sauutmhj

sauutmhj1#

我知道为什么会这样了。
有一个重要的注意事项,我忘了包括在原来的描述是,这发生在开发环境中工作。
this answer有关,之前我用Postico手动插入了一些数据,肯定是明确包含了including id,当时pkey序列没有更新,导致后来设置了重复的id。

bf1o4zei

bf1o4zei2#

医生
替换

|> unique_constraint(:name)

|> unique_constraint(:name, name: :rooms_pkey)

==============
unique_constraint并不像您所期望那样工作。
在您发布的示例中,原子:name被传递到unique_constraint。
默认情况下,从表+字段推断约束名称。对于复杂情况,可能需要显式指定
这就是为什么变更集定义:rooms_name_index,即使实际索引是:rooms_pkey。您必须显式地使用:name选项,以避免在ecto中出现这种默认行为。

c3frrgcw

c3frrgcw3#

我的可能是一个利基案例,但我在几年前从另一个表导入了ID高得多的记录,我的postgres版本最终赶上了。
我必须遵循这里列出的步骤Reset auto increment counter in postgres,即运行:

ALTER SEQUENCE product_id_seq RESTART WITH X

直接在postgres DB上重置产品表上的ID计数器。

相关问题