Изменить начальный идентификационный номер
У меня есть модель "Учетная запись" в 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
Ответы
Ответ 1
Для получения этой функциональности вам понадобится специальный SQL-зависимый SQL-запрос.
Если вы используете MySQL, вы можете добавить следующий код в свою миграцию после кода create_table
:
execute("ALTER TABLE tbl AUTO_INCREMENT = 1000")
Ответ 2
для PostgreSQL:
execute("ALTER SEQUENCE accounts_id_seq START with 1000 RESTART;")
см. https://www.postgresql.org/docs/current/static/sql-altersequence.html
Ответ 3
Для 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';
Ответ 4
Другая возможная концепция может заключаться в том, чтобы просто использовать переменную start_at в файле модели?
Например, определите базовый номер, такой как start_at = 53131
а затем... Создайте метод доступа (который может называться "ключом"), который добавляет ваш номер start_at
к реальному идентификатору базы данных перед его возвратом.
И вы можете создать метод записи attr, который вычитает 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%, но, по крайней мере, вам не придется изменять базу данных, чтобы справиться с этим.
Ответ 5
Чистым Ruby, независимым от базы данных, может быть:
class MyModel
before_create do
self.id = [1000, self.class.maximum(:id)+1].max if self.id.nil?
end
end
Когда вы создаете много записей одновременно, это может работать не так хорошо.
Ответ 6
в 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