简体   繁体   English

如何从 Rails 中的数据库列中删除唯一约束?

[英]How can I remove a unique constraint from a database column in Rails?

I created a table using the following migration:我使用以下迁移创建了一个表:

class CreateProfilePictures < ActiveRecord::Migration
  def change
    create_table :profile_pictures do |t|
      t.integer :user_id, null: false
      t.integer :picture_id, null: false
      t.timestamps null: false
    end

    add_index :profile_pictures, :user_id, unique: true
    add_index :profile_pictures, :picture_id, unique: true
  end
end

I tried to remove the constraint with the following:我试图通过以下方式删除约束:

class FixProfilePic < ActiveRecord::Migration
  def change
    change_column :profile_pictures, :picture_id, :integer, unique: false
  end
end

I still get a unique constraint violation error if I try to use the same picture_id in more than one place.如果我尝试在多个地方使用相同的 picture_id,我仍然会遇到违反唯一约束的错误。 What is the proper way to remove the uniqueness constraint from picture_id?从 picture_id 中删除唯一性约束的正确方法是什么?

You must remove your index with:您必须使用以下命令删除索引:

remove_index :profile_pictures, :picture_id

and add it again with:并再次添加:

add_index :profile_pictures, :picture_id

ActiveRecord::Migration ActiveRecord::迁移

add_index :profile_pictures, :picture_id, unique: true add_index :profile_pictures, :picture_id, 唯一: true

So update your index to:因此,将您的索引更新为:

  remove_index :profile_pictures, :picture_id
  add_index :profile_pictures, :picture_id

I'm guessing this is it.我猜是这个

There is a problem with the accepted answer: Rollbacks don't work correctly as the unique index is not restored.接受的答案存在问题:回滚无法正常工作,因为未恢复唯一索引。

You could try this instead:你可以试试这个:

reversible do |dir|
  dir.up do
    remove_index :profile_pictures, :picture_id
    add_index :profile_pictures, :picture_id
  end

  dir.down do
    remove_index :profile_pictures, :picture_id
    add_index :profile_pictures, :picture_id, unique: true
  end
end

For the migration to be reversible, you now (Rails 6+) need to use the :column option.为了使迁移可逆,您现在(Rails 6+)需要使用:column选项。

Adding unique: true also ensures rolling back the migration will recreate the index with the uniqueness constraint (barring problematic data being inserted in the meantime).添加unique: true还确保回滚迁移将重新创建具有唯一性约束的索引(除非同时插入有问题的数据)。

  remove_index :profile_pictures, column: :picture_id, unique: true
  add_index :profile_pictures, :picture_id

One more thing to note: if your table is large, then creating a new index on it could lock writes to it for a long time.还有一点需要注意:如果您的表很大,那么在其上创建新索引可能会长时间锁定对其的写入。 Consider using algorithm: :concurrently if you use Postgres考虑使用algorithm: :concurrently如果你使用 Postgres

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM