更改起始ID号

我在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 

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

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

 execute("ALTER TABLE tbl AUTO_INCREMENT = 1000") 

对于PostgreSQL:

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

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

对于sqlite

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

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

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

如果sequence.empty?

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

其他

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

另一个可能的概念可能是在模型文件中使用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 

不确定这是多么实用,或者它甚至可以10​​0%工作,但至少你不必修改数据库来处理它。

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

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

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

在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