Rails3 bigint 主键

发布于 2024-11-04 15:30:16 字数 545 浏览 0 评论 0原文

我想在 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 也是如此。

I would like to create a bigint (or string or whatever that is not int) typed primary key field under Rails 3.

I have a given structure of data, for example:

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

The approach I'm currently trying to push:

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

The column type will be correct, but the primary key option will not be present with sqlite3 and I suspect that this is the case for MySQL too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

抽个烟儿 2024-11-11 15:30:16

我也有同样的问题。我认为表
最简单的方法

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"

I had the same problem. I think the easiest way for a table

accounts 
id bigint primary key 
name char 

is

create_table :accounts do |t|
t.string :name
end
change_column :accounts, :id , "bigint NOT NULL AUTO_INCREMENT"
谁对谁错谁最难过 2024-11-11 15:30:16

不久前我自己也有这个问题,并在这里找到了答案:使用Rails,如何将主键设置为不是整数类型列?

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

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

Had that myself not long ago and found the answer here: Using Rails, how can I set my primary key to not be an integer-typed column?

You need to set primary_key: false and then use a custom statement before you execute the migration.

EDIT 1: You need to check your database docs for the exact query to perform. It is executed as a regular SQL statement and needs to be database specific. The example in the question I referred to is for Postgre SQL. If you are on MySQL you might have to change that.

多像笑话 2024-11-11 15:30:16

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

class ChangeUserIdToBigint < ActiveRecord::Migration
  def change
    change_column :users, :id, 'SERIAL'
  end
end

For MySQL you can use "SERIAL" which is alias for "BIGINT UNSIGNED NOT NULL AUTO_INCREMENT"

class ChangeUserIdToBigint < ActiveRecord::Migration
  def change
    change_column :users, :id, 'SERIAL'
  end
end
入怼 2024-11-11 15:30:16

对于那些来到这里(像我一样)努力弄清楚如何制作使用 bigint 而不是 int 的自定义 id 列的人code>,我没有意识到的是,对于 Rails 5.1 及更高版本,bigintid

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

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

路还长,别太狂 2024-11-11 15:30:16

skalogirou 的答案很好,但更改不会反映在 schema.rb 中。因此像 db:schema:load 和 db:test:clone 这样的任务不会创建相同的数据库结构。

所需的解决方法是增强 db:schema:load 和 db:test:clone rake 任务,如下所述:
http://www.lshift.net/blog/2013/09/30/changing-the-primary-key-type-in​​-ruby-on-rails-models/

这是我用的基于该解决方法:

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

skalogirou's answer is good but the change will not be reflected in schema.rb. So the tasks like db:schema:load and db:test:clone will not create identical DB structure.

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
山田美奈子 2024-11-11 15:30:16

如果你想转换 Postgres 中的所有表,你将需要运行此代码

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文