【问题标题】:Problems setting a custom primary key in a Rails 4 migration在 Rails 4 迁移中设置自定义主键的问题
【发布时间】:2013-10-03 18:19:56
【问题描述】:

我使用 postgresql 9.3、Ruby 2.0、Rails 4.0.0。

在阅读了许多关于在表上设置主键的 SO 问题后,我生成并添加了以下迁移:

class CreateShareholders < ActiveRecord::Migration
  def change
    create_table :shareholders, { id: false, primary_key: :uid  } do |t|
      t.integer :uid, limit: 8
      t.string :name
      t.integer :shares

      t.timestamps
    end
  end
end

我还在我的模型中添加了self.primary_key = "uid"

迁移成功运行,但是当我使用 pgAdmin III 连接到数据库时,我看到 uid 列未设置为主键。我错过了什么?

【问题讨论】:

    标签: ruby-on-rails ruby postgresql primary-key database-migration


    【解决方案1】:

    看看this answer。尝试 execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);" 而不在 create_table 块中指定 primary_key 参数。

    我建议你像这样写你的迁移(这样你就可以正常回滚):

    class CreateShareholders < ActiveRecord::Migration
      def up
        create_table :shareholders, id: false do |t|
          t.integer :uid, limit: 8
          t.string :name
          t.integer :shares
    
          t.timestamps
        end
        execute "ALTER TABLE shareholders ADD PRIMARY KEY (uid);"
      end
    
      def down
        drop_table :shareholders
      end
    end
    

    UPD:有自然方式(found here),但仅限 int4 类型:

    class CreateShareholders < ActiveRecord::Migration
      def change
        create_table :shareholders, id: false do |t|
          t.primary_key :uid
          t.string :name
          t.integer :shares
    
          t.timestamps
        end    
      end
    end
    

    【讨论】:

    • 这正是我错过的问题。虽然我能够做到这一点,但我想知道是否有办法以“自然”的方式实现这一点,即不执行直接 sql 查询。尽管如此,由于没有任何其他建议,我接受此作为最佳答案。 :)
    • 但是在这种情况下主键的类型是什么?我需要它是 bigint。
    • 抱歉,错过了。它是int4。然而这种方式不适合我们。
    • 由于 primary_key 方法只接受一个参数,我认为除了使用普通 sql 来实现 bigint 之外别无他法。
    • 默认情况下,Rails 5.1 中的主键是 bigint:github.com/rails/rails/pull/26266
    【解决方案2】:

    在我的环境中(activerecord 3.2.19 和 postgres 9.3.1),

    :id => true, :primary_key => "columname"
    

    成功创建主键,但没有指定 ":limit => 8",列的类型是 int4!

    create_table :m_check_pattern, :primary_key => "checkpatternid" do |t|
      t.integer     :checkpatternid, :limit => 8, :null => false
    end
    

    抱歉信息不完整。

    【讨论】:

      【解决方案3】:

      我已经创建了这样的迁移:

      class CreateShareholders < ActiveRecord::Migration
        def change
          create_table :shareholders, id: false do |t|
            t.integer :uid, primary_key: true
            t.string :name
            t.integer :shares
      
            t.timestamps
          end    
        end
      end
      

      【讨论】:

        猜你喜欢
        • 2011-09-18
        • 1970-01-01
        • 1970-01-01
        • 2013-05-31
        • 1970-01-01
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        相关资源
        最近更新 更多