更改起始ID号

时间:2010-01-15 23:03:32

标签: ruby-on-rails

我在Rails中有一个“帐户”模型,在数据库中有相应的“帐户”表。如果我擦除数据库并重新开始,'account_id'字段将始终从1开始并从那里开始计数。我想更改起始编号,这样,当在新数据库中创建第一个帐户时,'account_id'就是1000.有没有办法在Rails中执行此操作,或者我是否需要专门的数据库依赖SQL代码?

为了便于说明,这里是我的“帐户”表的简化版本:

create_table "accounts", :force => true do |t|
  t.string   "email", :null => false
  t.string   "crypted_password", :null => false
  t.string   "name", :null => false
  t.boolean  "email_verified", :default => false
end

6 个答案:

答案 0 :(得分:14)

对于PostgreSQL:

execute("ALTER SEQUENCE accounts_id_seq START with 1000 RESTART;")

请参阅https://www.postgresql.org/docs/current/static/sql-altersequence.html

答案 1 :(得分:10)

您需要执行一些专门的数据库相关SQL才能获得此功能。

如果您使用的是MySQL,则可以在create_table代码后向迁移中添加以下代码:

execute("ALTER TABLE tbl AUTO_INCREMENT = 1000")

答案 2 :(得分:5)

对于sqlite

序列存储在表sqlite_sequence(name,seq)

  • 首先检查序列是否已存在?

    select name,seq from sqlite_sequence where name = 'accounts'

if sequence.empty?

insert into sqlite_sequence(name,seq) values('accounts', 1000);

否则

update sqlite_sequence set seq = 1000 where name = 'accounts';

答案 3 :(得分:2)

另一个可能的概念可能是在模型文件中使用start_at变量吗?

例如定义start_at = 53131等基数,然后...... 创建一个访问器方法(可以称之为“密钥”),在返回之前将start_at编号添加到数据库的真实ID中。

你可以制作一个attr writer方法,在保存密钥之前减去start_at,根据你的实现,这可能根本不需要。

伪代码中的示例请耐心等待。

class FakeModel
  attr_accessible :name
  start_at = 53121

  def self.find_by_key(key)
    find_by_id(key-start_at))
  end

  def key
    (self.id+start_at)
  end
end

不确定这是多么实用,或者它是否能100%正常工作,但至少你不必修改数据库来处理它。

答案 4 :(得分:2)

纯Ruby,独立于数据库的方法可能是:

class MyModel
  before_create do
    self.id = [1000, self.class.maximum(:id)+1].max if self.id.nil?
  end
end

当你一次创建大量记录时,这可能表现不佳。

答案 5 :(得分:0)

SQL Server中的

execute('DBCC CHECKIDENT (accounts, reseed, 1000)')

就我而言,开发环境和生产环境使用不同类型的数据库。

此代码块将按照DB类型运行相关执行 - 只需将其置于相关的迁移中:

puts 'Migration trys to set initial account ID to adapter:' + ActiveRecord::Base.connection.adapter_name
case ActiveRecord::Base.connection.adapter_name
  when 'MySQL'
    execute('ALTER TABLE accounts AUTO_INCREMENT = 1000')
  when 'SQLServer'
    execute('DBCC CHECKIDENT (accounts, reseed, 1000)')
  when 'SQLite'
    begin
      execute('insert into sqlite_sequence(name,seq) values(\'accounts\', 1000);')
    rescue
      puts 'insert error... updating'
    end
    execute('update sqlite_sequence set seq = 1000 where name = \'accounts\';')
  else
    puts "cant recognize the database"
end