Ecto - 无法删除自定义命名的唯一索引

skw*_*eth 9 elixir ecto

我无法成功运行 Ecto 迁移来删除唯一索引,该索引在最初创建时已提供:name属性的唯一索引(以便不使用默认索引名称)。但是,我现在无法删除该索引,因为 Ecto 似乎正在尝试查找名称不正确的索引(尽管我已经提供了它)。

唯一索引最初是通过迁移创建的,如下所示:

def change do
  create(
    unique_index("foo", [:bar_id],
      where: "rejected IS NULL AND accepted IS NULL)",
      name: :bar_pending_index
    )
  )
end
Run Code Online (Sandbox Code Playgroud)

当我检查 psql shell 中的表时,我看到该索引列出为:

"bar_pending_index" UNIQUE, btree (bar_id) WHERE rejected IS NULL AND accepted IS NULL
Run Code Online (Sandbox Code Playgroud)

为了删除索引,我编写了以下迁移:

def up do
  drop index("foo", [:bar_pending_index])
end

def down do
  create(
    unique_index("foo", [:bar_id],
      where: "rejected IS NULL AND accepted IS NULL)",
      name: :bar_pending_index
    )
  )
end
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行此迁移时,出现错误

14:01:56.573 [info]  == Running 20210610173741 MyApp.Repo.Migrations.DropIndex.up/0 forward

14:01:56.576 [info]  drop index foo_bar_pending_index_index
** (Postgrex.Error) ERROR 42704 (undefined_object) index "foo_bar_pending_index" does not exist
Run Code Online (Sandbox Code Playgroud)

在我看来,它似乎试图应用 Ecto 通常认为的“默认”命名约定,也就是说,它希望在索引名称前面加上表名称,并在索引名称后面加上单词“index”。通过 Ecto 迁移删除自定义命名索引的正确方法是什么?谢谢你!

sba*_*rob 10

当您这样做时,drop index("foo", [:bar_pending_index])您将调用用于创建索引的相同index/3函数,类似于unique_index/3.

查看这两个函数的文档,您会注意到第二个参数始终是用于索引的列(drop:上的示例drop index("posts", [:name])由于列名而有点模糊:name)。

因此,您应该做的实际上与创建索引的方式非常相似,例如:

drop index("foo", [:bar_id], name: :bar_pending_index)
Run Code Online (Sandbox Code Playgroud)