迁移错误:ENUM类型已存在

时间:2018-02-15 21:10:39

标签: ruby-on-rails postgresql enums

关于版本:

  • Rails:5.1.4
  • PostgreSQL:9.6.1.0

我有两个具有ENUM状态的模型,当我尝试为第二个模型运行迁移时出现此错误:

  

PG :: DuplicateObject:错误:类型“状态”已存在:
  创建类型状态为ENUM('已创建','已发布','已存档');   /Ruby/Projects/Apps/alpsplease/alps_app/db/migrate/20180215204243_add_status_to_experiences.rb:3:in   `向上“

     

引起:ActiveRecord :: StatementInvalid:PG :: DuplicateObject:ERROR:   类型“status”已存在:CREATE TYPE status AS ENUM   ('已创建','已发布','已存档');   /Ruby/Projects/Apps/alpsplease/alps_app/db/migrate/20180215204243_add_status_to_experiences.rb:3:in   `向上“

     

引起:PG :: DuplicateObject:错误:类型“status”已存在   /Ruby/Projects/Apps/alpsplease/alps_app/db/migrate/20180215204243_add_status_to_experiences.rb:3:in   'up'任务:TOP => db:migrate(通过运行任务查看完整跟踪   --trace)

为第二个模型生成相同的ENUM类型或将现有类型添加到第二个模型的正确方法是什么?因为像“status_model”这样创建ENUM看起来不是理想的解决方案。

迁移代码:

class AddStatusToExperiences < ActiveRecord::Migration[5.1]
  def up
    execute <<-SQL
      CREATE TYPE status AS ENUM ('created', 'published', 'archived');
    SQL

    add_column :experiences, :status, :status, default: 'created', index: true
  end

  def down
    remove_column :experiences, :status

    execute <<-SQL
      DROP TYPE status;
    SQL
  end
end

1 个答案:

答案 0 :(得分:0)

由于您之前的模型已经有self.close_button = tk.Button(..., command=self.top.destroy) 枚举类型,因此解决方案非常简单明了:只需将类型指定为status即可。迁移中没有其他:statusCREATE TYPE

只要知道如果修改枚举类型,使用它的所有表当然会受到可能值范围的影响。尽管如此,如果您想在某个时刻添加新值,请提供以下提示:您需要为此禁用数据库事务。即。

DROP TYPE

有关共享枚举类型的更多信息,请参阅此帖子: Share enum declaration values between models

如果您不想共享该类型(即它们偶然具有相同的名称但可能的值集合不同),您可以通过class AddNewStatus < ActiveRecord::Migration[5.0] disable_ddl_transaction! # enums cannot be altered from within a transaction def change execute <<-SQL ALTER TYPE status ADD VALUE 'foobar'; SQL end end 重命名现有类型并发出另一个类型ALTER TYPE status RENAME TO experience_status使用之前的第二个名称,引用第二个表的列的新类型。