Rails 不能 运行 remove_index

Rails cannot run remove_index

我不小心这样添加了索引:

class AddRandomIndices < ActiveRecord::Migration[5.0]
  def change
    add_index :charges, :pp_charge_id
    add_index :new_refunds, :pp_refund_id
    add_index :inventory_items, :product_id, unique: true
    add_index :prestock_items, :product_id, unique: true
  end
end

这是架构中的结果:

create_table "charges", force: :cascade do |t|
  ...
  t.index ["pp_charge_id"], name: "index_charges_on_pp_charge_id", using: :btree
end

create_table "new_refunds", force: :cascade do |t|
  ...
  t.index ["pp_refund_id"], name: "index_new_refunds_on_pp_refund_id", using: :btree
end
  

create_table "prestock_items", force: :cascade do |t|
  ...
  t.index ["product_id"], name: "index_prestock_items_on_product_id", unique: true, using: :btree
end

create_table "inventory_items", force: :cascade do |t|
  ...
  t.index ["product_id"], name: "index_inventory_items_on_product_id", unique: true, using: :btree
end

这是我尝试删除的文件 运行:

class RemoveIndex < ActiveRecord::Migration[5.0]
  def change
    remove_index :charges, :pp_charge_id
    remove_index :new_refunds, :pp_refund_id
    remove_index :inventory_items, :product_id
    remove_index :prestock_items, :product_id
  end
end

这是错误

> rake db:migrate
== 20220515045335 RemoveIndex: migrating ======================================
-- remove_index(:charges, :pp_charge_id)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

No indexes found on charges with the options provided.

在另一个 SO 答案中:How to remove index in rails,有很多建议的选项...none 其中有效。

这里我尝试运行一个明确指定列和名称的文件

class RemoveIndex < ActiveRecord::Migration[5.0]
  def change
    remove_index :charges, column: :pp_charge_id, name: :index_charges_on_pp_charge_id
    remove_index :new_refunds, column: :pp_refund_id, name: :index_new_refunds_on_pp_refund_id
    remove_index :inventory_items, column: :product_id, name: :index_prestock_items_on_product_id
    remove_index :prestock_items, column: :product_id, name: :index_inventory_items_on_product_id
  end
end

同样的错误:

> rake db:migrate
== 20220515045335 RemoveIndex: migrating ======================================
-- remove_index(:charges, {:column=>:pp_charge_id, :name=>:index_charges_on_pp_charge_id})
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

No indexes found on charges with the options provided.

然后我尝试 运行 文件只有名字,没有列

class RemoveIndex < ActiveRecord::Migration[5.0]
  def change
    remove_index :charges, name: :index_charges_on_pp_charge_id
    remove_index :new_refunds, name: :index_new_refunds_on_pp_refund_id
    remove_index :inventory_items, name: :index_prestock_items_on_product_id
    remove_index :prestock_items, name: :index_inventory_items_on_product_id
  end
end

不同的错误:

> rake db:migrate
== 20220515045335 RemoveIndex: migrating ======================================
-- remove_index(:charges, {:name=>:index_charges_on_pp_charge_id})
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedObject: ERROR:  index "index_charges_on_pp_charge_id" does not exist
: DROP INDEX  "index_charges_on_pp_charge_id"

我也试过传递字符串,并且会省去后续的 copy/pasting...

发生了什么??!

您使用的删除索引的语法是正确的,不确定会发生什么,但是最好使用 SQL 查询检查数据库中是否确实存在索引,您可以在这里找到它:

架构会自动与数据库同步,但在您的情况下,您的迁移会引发错误,这就是它未更新的原因,因此您可以尝试删除引发错误的迁移,然后 运行ning rails db:migrate,如果数据库中不存在索引,它们也会从架构中删除。

通常,如果您错误地添加了一些迁移并且尚未将其推送到版本控制或尚未与其他任何人共享,那么您可以 运行 rails db:rollback 如果这是最后一次迁移或 运行 rails db:migrate:status 获取要回滚的迁移版本号,然后 运行 rails db:migrate:down VERSION=20220515045335 (仅当迁移状态为 up 时才会 运行 )这将回滚迁移,然后您可以安全地删除文件。