9

我想在 Rails 3 下创建一个bigint(或string其他不是)类型的主键字段。int

我有一个给定的数据结构,例如:

things
------
id bigint primary_key
name char(32)

我目前正在尝试推动的方法:

create_table :things, :id => false do |t| # That prevents the creation of (id int) PK
  t.integer :id, :limit => 8 # That makes the column type bigint
  t.string :name, :limit => 32
  t.primary_key :id # This is perfectly ignored :-(
end

列类型将是正确的,但 sqlite3 不会出现主键选项,我怀疑 MySQL 也是这种情况。

4

6 回答 6

5

我有同样的问题。我认为最简单的方法是一张桌子

accounts 
id bigint primary key 
name char 

create_table :accounts do |t|
t.string :name
end
change_column :accounts, :id , "bigint NOT NULL AUTO_INCREMENT"
于 2012-09-20T14:27:21.650 回答
3

如果我自己不久前在这里找到了答案:Using Rails, how can I set my primary key to not be an integer-typed column?

您需要设置 primary_key: false 然后在执行迁移之前使用自定义语句。

编辑 1:您需要检查数据库文档以执行确切的查询。它作为常规 SQL 语句执行,并且需要特定于数据库。我提到的问题中的示例是针对 Postgre SQL 的。如果您使用的是 MySQL,您可能需要更改它。

于 2011-05-04T08:38:46.230 回答
3

对于 MySQL,您可以使用“SERIAL”,它是“BIGINT UNSIGNED NOT NULL AUTO_INCREMENT”的别名

class ChangeUserIdToBigint < ActiveRecord::Migration
  def change
    change_column :users, :id, 'SERIAL'
  end
end
于 2013-09-30T17:40:33.783 回答
1

For those of you who came here (like I did) in an effort to figure out how to make a custom id column that uses bigint instead of int, what I didn't realize is that for Rails 5.1 and above, bigint is the default type for id

https://github.com/rails/rails/pull/26266

于 2020-06-23T14:39:23.700 回答
0

skalgirou 的回答很好,但更改不会反映在 schema.rb 中。所以任务喜欢db:schema:load并且db:test:clone不会创建相同的数据库结构。

The required workaround is to enhance db:schema:load and db:test:clone rake tasks as described here: http://www.lshift.net/blog/2013/09/30/changing-the-primary-key-type-in-ruby-on-rails-models/

This is what I used based on that workaround:

namespace :my_app do
  namespace :db do
    task :after_schema_load_and_db_test_clone => :environment do
    puts 'Changing primary key for :my_table'
    query = 'ALTER TABLE <my_table> CHANGE id id bigint DEFAULT NULL auto_increment'
    ActiveRecord::Base.connection.execute(query)
  end
end


Rake::Task['db:schema:load'].enhance do
  ::Rake::Task['my_app:db:after_schema_load_and_db_test_clone'].invoke
end

Rake::Task['db:test:clone'].enhance do
  ::Rake::Task['my_app:db:after_schema_load_and_db_test_clone'].invoke
end
于 2015-01-08T13:51:11.897 回答
0

If you want to convert all tables in Postgres you will need to run this code

class ConvertIntToBigint < ActiveRecord::Migration[5.1]
  def up
    query = <<-SQL
      SELECT tablename AS "tablename"
      FROM pg_tables
      WHERE schemaname = 'public';
    SQL
    connection.execute(query).each do |element|
      if column_exists?(element['tablename'], :id, :integer)
        change_table(element['tablename']) {|t| t.change :id, :bigint }
      end
    end
  end

  def down
  end
end
于 2018-01-17T13:34:30.423 回答