在运行rake db:migrate时,创建迁移以向表添加列的Rails会导致错误

Cat*_*ish 22 ruby migration ruby-on-rails ruby-on-rails-3

我有一个名为"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`.....
Run Code Online (Sandbox Code Playgroud)

为什么要再次创建表?

这是我用来创建新迁移的命令

$ 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
Run Code Online (Sandbox Code Playgroud)

新迁移如下所示:

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
Run Code Online (Sandbox Code Playgroud)

编辑

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

oma*_*ous 11

Rails在数据库的"schema_migrations"表中跟踪迁移.除非存在"20120511224920"的条目,即Devise迁移,否则它将尝试再次运行它,它似乎已经存在.

如果是这种情况,您可以手动将其添加到表中.

  • 我没有意识到这一点.我运行了一个rake db:reset,所以现在唯一的迁移是一个新的.如果我知道schema_migrations表,我至少可以检查一下. (2认同)

Gor*_*McD 6

该错误表明它正在尝试再次运行原始DeviseCreateUsers迁移,因为users表已经存在而无法运行.

要解决此问题,您可以运行向下迁移DeviseCreateUsers,然后正常运行迁移.你可以这样做:

rake db:migrate:down VERSION=20121031XXXXXXXX
rake db:migrate
Run Code Online (Sandbox Code Playgroud)

20121031XXXXXXXX迁移名称的日期戳在哪里.换句话说,您将命名一个迁移,20120410214815_devise_create_users.rb并从文件名中复制日期戳并将其粘贴到命令中.这是关于迁移的Rails指南以供参考.

编辑:这在评论中注明,但只是一个警告.对表执行向下迁移将丢失表所具有的任何条目.我假设你在开发模式下运行,所以这应该不是问题.如果你正在制作中,你将需要采取额外的步骤来备份表数据并在之后重新加载它,否则你将会有糟糕的一天(或者可能是一周).


Tha*_*anh 5

您可以尝试创建一个新的数据库,然后再次迁移它:

rake db:drop:all
rake db:create:all
rake db:migrate
Run Code Online (Sandbox Code Playgroud)