无法从 Rails 4 和 PSQL 9.3 中的表中删除索引

Posted

技术标签:

【中文标题】无法从 Rails 4 和 PSQL 9.3 中的表中删除索引【英文标题】:Cannot remove an index from table in Rails 4 and PSQL 9.3 【发布时间】:2013-10-31 11:12:08 【问题描述】:

在我的 schema.rb 我有以下行:

add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree

当我在 psql 中运行 \di 时,我得到:

Schema |                             Name                             | Type  | Owner |         Table
--------+--------------------------------------------------------------+-------+-------+-----------------------
 public | index_users_on_email                                         | index | alex  | users

但是,如果我在迁移中包含以下之一:

remove_index:用户,名称::index_users_on_email remove_index:用户,列::电子邮件 remove_index :users, :email 执行“删除索引 index_users_on_email”

我收到以下错误:

rake aborted!
An error has occurred, this and all later migrations canceled:

Index name 'index_users_on_email' on table 'users' does not exist

我还发现了这个issue。那么有什么想法吗?

【问题讨论】:

【参考方案1】:

我的错误:试图删除我正在删除的列上的索引。

迁移正在提升PG::UndefinedObject: ERROR: index "index_candidates_on_job_id_and_email" does not exist

class MergeJobAndJobCandidateModels < ActiveRecord::Migration[6.0]
  # ...
  def down
    change_table :candidates do |t|
      t.remove :job_id
      # ...
    end
    remove_index :candidates, %i[email job_id]
  end
end

错误:我正在删除列并试图删除索引。 Rails/Postgres 将自动删除不再存在的列上的索引,因此我没有理由在迁移中删除此索引。

希望这可以为遇到此错误的其他人节省一点时间。

【讨论】:

【参考方案2】:

我知道这来得太晚了,但我遇到了类似的事情。在尝试删除索引之前,您是否有机会重命名“电子邮件”列?如果是这样,通过重命名列,索引将被删除。所以顺序必须是:

1) 删除索引 2) 重命名列

【讨论】:

这也是我的问题。我正在删除一列,然后尝试删除包含先前删除的列的索引。 这里也一样。我正在运行删除列然后删除索引并收到此错误的迁移。换了顺序,效果很好。【参考方案3】:

答案有点晚了,但我刚刚遇到了同样的问题,所以我写下这个答案,希望它能在未来对其他人有所帮助。

原始提问者遇到的issue 导致了解决方案。在 Rails 3.x 中,index_name_for_remove 的 the implementation 似乎存在缺陷,因此有时它不接受命名索引。相反,它提出了一个ArgumentError 声称该索引不存在。

在 Rails 4.x 中,the implementation 已更改,以便正确处理传递带有索引名称的哈希(我想,我目前没有可供测试的 Rails 4 应用程序)。

如果您需要在 Rails 3.x 中处理此问题,请查看 remove index 的源代码 - 使用 remove_index! 方法。 remove_index! 有两个参数——表名和索引名。所以在原始发帖人的问题的情况下,这个命令应该可以完成这项工作:

remove_index! :users, :index_users_on_email

更新:发布答案后,我注意到原发帖人在询问 Rails 4,所以在某些情况下,index_name_for_remove 的实现似乎仍然存在问题,没有检测到正确的索引名称。但是,由于索引的名称是已知的,并且我们不需要实际找出名称是什么(这是index_name_for_remove 内部所做的),我们仍然可以使用remove_index! 方法将其删除。

【讨论】:

对于 rails 3,remove_index! :table_name, :index_name 有效。谢谢!【参考方案4】:

如果你想按名称删除索引,你可以这样写:

remove_index(:table_name, :name => 'index_name')

你也应该看看这个问题:What's the correct syntax for remove_index in a Rails 3.1.0 migration?

【讨论】:

我已经尝试按名称删除索引,但得到了相同的结果。我也读过你提到的问题。不过还是谢谢你的努力。 你应该手动检查你的数据库,看看索引是否真的存在。 是的,它确实存在。在 psql 中运行 \di 给出:public | index_users_on_email | index | alex | users @AlexPopov 你找到答案了吗?在 mysql 上遇到同样的错误。

以上是关于无法从 Rails 4 和 PSQL 9.3 中的表中删除索引的主要内容,如果未能解决你的问题,请参考以下文章

脚手架后无法迁移 psql 数据库 - Cloud9

如何在黄瓜rails中将mysql转换为psql

无法从 golang 连接到 docker postgres 容器

无法从 BASH 脚本中运行 psql 命令

Rails 3.1 & RestKit 0.9.3 - 引用映射

rails应用程序非常慢