Rails, создающий миграцию для добавления столбцов в таблицу, вызывает ошибку при запуске rake db: migrate
У меня есть модель, созданная с именем "users", и я создал новую миграцию, чтобы добавить некоторые столбцы в таблицу users. Теперь, когда я запускаю rake db: migrate, я получаю ошибку ниже b/c, пытаясь снова создать таблицу users
$ rake db:migrate
== DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:
Mysql::Error: Table 'users' already exists: CREATE TABLE `users`.....
Почему он пытается снова создать таблицу?
Здесь команда, которую я использовал для создания новой миграции
$ rails generate migration AddDetailsToUsers home_phone:decimal cell_phone:decimal work_phone:decimal birthday:date home_address:text work_address:text position:string company:string
Новая миграция выглядит следующим образом:
class AddDetailsToUsers < ActiveRecord::Migration
def change
add_column :users, :home_phone, :decimal
add_column :users, :cell_phone, :decimal
add_column :users, :work_phone, :decimal
add_column :users, :birthday, :date
add_column :users, :home_address, :text
add_column :users, :work_address, :text
add_column :users, :position, :string
add_column :users, :company, :string
end
end
ИЗМЕНИТЬ
20120511224920_devise_create_users
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => ""
t.string :username, :null => false, :default => ""
t.string :encrypted_password, :null => false, :default => ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, :default => 0
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Encryptable
# t.string :password_salt
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
## Token authenticatable
# t.string :authentication_token
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
end
20120619023856_add_name_to_users
class AddNameToUsers < ActiveRecord::Migration
def change
add_column :users, :first_name, :string
add_column :users, :last_name, :string
end
end
20121031174720_add_details_to_users.rb
class AddDetailsToUsers < ActiveRecord::Migration
def change
add_column :users, :home_phone, :decimal
add_column :users, :cell_phone, :decimal
add_column :users, :work_phone, :decimal
add_column :users, :birthday, :date
add_column :users, :home_address, :text
add_column :users, :work_address, :text
add_column :users, :position, :string
add_column :users, :company, :string
end
end
Ответы
Ответ 1
Rails отслеживает миграцию в таблице "schema_migrations" вашей базы данных. Если нет записи для "20120511224920", которая является миграцией Devise, она попытается запустить ее снова, которая, как представляется, уже существует.
Вы можете добавить это вручную в таблицу, если это так.
Ответ 2
Ошибка говорит о том, что она пытается снова запустить первоначальную миграцию DeviseCreateUsers и не может, поскольку таблица пользователей уже существует.
Чтобы исправить это, вы можете запустить миграцию вниз для DeviseCreateUsers
, а затем выполнить миграцию как обычно. Вы можете сделать это с помощью
rake db:migrate:down VERSION=20121031XXXXXXXX
rake db:migrate
Где 20121031XXXXXXXX
- это отметка даты имени миграции. Другими словами, вы будете иметь миграцию с именем 20120410214815_devise_create_users.rb
и скопируете штамп даты из имени файла и вставьте его в команду. Здесь Rails Guide on Migrations для справки.
Изменить: Это отмечено в комментариях, а всего лишь слово предупреждения. Выполнение переноса вниз для таблицы приведет к потере любых записей, которые есть в таблице. Я предполагаю, что вы работаете в режиме разработки, поэтому это не должно быть проблемой. Если вы находитесь в производстве, вам нужно будет предпринять дополнительные шаги для резервного копирования данных таблицы и перезагрузки после этого, иначе у вас будет плохой день (или, возможно, неделя).
Ответ 3
Можете ли вы попробовать создать новую базу данных, а затем перенести ее снова:
rake db:drop:all
rake db:create:all
rake db:migrate
Ответ 4
Итак, из того, что я собрал из этого:
- У вас уже была модель пользователя
- У вас есть версия этого в производстве
- Вы запускали по умолчанию rails generate devise: install
- Затем вы запустили рельсы, генерирующие dev. Пользователь
Я надеюсь, что:
- Вы используете источник управления
- Вы часто проверяете код
ПРИМЕЧАНИЕ. Если нет, вы узнаете, зачем вам это нужно.
Отмените свой код до того, как вы создали Devise
Надеюсь, вы можете просто создать новую песочницу точки прямо перед генерацией. Если нет, скопируйте каталог проекта и сделайте это вручную. Единственный другой вариант - это вручную отредактировать все файлы, созданные Devise.
Повторите создание своего поколения
- readd gem 'devise' в ваш Gemfile
- рельсы создают devise: install
- рельсы генерируют конструкцию MODEL
Убедитесь, что модель не существует! Если вы этого не сделаете, вы попадаете в проблему, которую вы в настоящее время имеете.
Перенос текущих пользователей из одной модели в другую
Если вы можете создать script, чтобы полностью перенести данные аутентификации из вашей старой пользовательской модели в новую, хорошо для вас. Если вы используете другой алгоритм хэширования из Devise для вашей текущей проверки подлинности, вы собираетесь либо аннулировать все свои пароли, либо потребовать от своих пользователей создания нового пароля с помощью кода подтверждения в своем письме или вы можете перенести пользователей по мере их регистрации Первый метод - чистый, полный и грубый. Второй метод является уродливым, неполным и бесшумным. Выберите свой метод, как вам нравится.
Изменить: вы, вероятно, можете найти способ настроить Devise для использования своего алгоритма. Это, вероятно, будет еще лучше, но немного больше работы и довольно хрупкой.
Другое дело, что ваша модель проверки подлинности не должна быть перегружена данными учетной записи. У вас должна быть модель, которая обрабатывает только аутентификацию, которая имеет модель данных учетной записи account_a, которая хранит все, что вы можете отслеживать в отношении учетных записей.
Ответ 5
используйте методы "вверх-вниз". Это будет полезно для отката и выполнения определенного файла миграции.
Пожалуйста, следуйте синтаксису..
class AddDetailsToUsers < ActiveRecord::Migration
def self.up
add_column :users, :home_phone, :decimal
add_column :users, :cell_phone, :decimal
add_column :users, :work_phone, :decimal
add_column :users, :birthday, :date
add_column :users, :home_address, :text
add_column :users, :work_address, :text
add_column :users, :position, :string
add_column :users, :company, :string
end
def self.down
remove_column :users, :home_phone
remove_column :users, :cell_phone
remove_column :users, :work_phone
remove_column :users, :birthday
remove_column :users, :home_address
remove_column :users, :work_address
remove_column :users, :position
remove_column :users, :company
end
end
In this case please try to migrate using version number.
Как rake db: migrate: down VERSION = номер версии # номер перевода - это версия, которую вы хотите перенести.
Ответ 6
Я предполагаю, что вы запустили rails generate devise user
sometime, который сгенерировал DeviseCreateUsers
. Если вы уже создали таблицу User model и users, вы можете удалить сгенерированный файл миграции из db/migrate.
Ответ 7
Проверьте некоторые переменные среды, которые могут поставлять неожиданное значение для версии вашей миграции. Я нашел старый вопрос о переполнении стека (и простить меня, если он устарел), где db:migrate
уничтожает таблицу, вместо применения существующей новой миграции,
В итоге они обнаружили, что переменная окружения вызывала db:migrate
для запуска с параметром версии "0", который функционально эквивалентен rake db:migrate:down
Возможно ли, что ваша ситуация может быть вызвана неожиданно измененной версией для включения или сопоставления предыдущей миграции DeviseCreateUsers
?
Ответ 8
просто попробуйте
в первом файле
create_table(:users), :force => true do |t|
это переопределит любую другую таблицу
Ответ 9
В соответствии с тем, что вы сказали, вы использовали эту команду для создания новой миграции
$rails сгенерировать миграцию AddDetailsToUsers home_phone: decimal cell_phone: decimal work_phone: decimal birthday: date home_address: text work_address: text position: string company: string
Я не уверен, что это просто опечатка, но это должно быть "AddDetailsToUser", а не "Пользователи". Просто проверьте еще раз, и мы сможем вам помочь. Это для разрабатываемой модели. Когда вы указываете User, в db он ищет пользователей.
Ruby on Rails следуют лингвистическому соглашению. имя_таблицы - это Plural, а имя_модель - Singular. Вы должны использовать имя модели в используемой вами команде.
Если вы хотите использовать имя_таблицы, используйте этот
rails g migration add_details_to_users home_phone: decimal...... и т.д.
Ответ 10
И если вам нужно выполнить некоторые грязные миграции вручную:
class A < ActiveRecord::Migration
def up
add_column :images, :name
end
end
A.new.migrate(:up)