耙子中止...表'用户'已经存在

时间:2011-10-24 10:34:37

标签: ruby-on-rails ruby database

我用devise和漂亮的生成器创建了一个数据库。我正在尝试使用漂亮的生成器(rails g nifty:scaffold Asset user_id:integer)创建一个新数据库,但是当我尝试迁移数据库(rake db:migrate)时,我收到以下错误:

charlotte-dator:showwwdown holgersindbaek$ rake db:migrate
==  DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'users' already exists: CREATE TABLE `users` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `email` varchar(255) DEFAULT '' NOT NULL, `encrypted_password` varchar(128) DEFAULT '' NOT NULL, `reset_password_token` varchar(255), `reset_password_sent_at` datetime, `remember_created_at` datetime, `sign_in_count` int(11) DEFAULT 0, `current_sign_in_at` datetime, `last_sign_in_at` datetime, `current_sign_in_ip` varchar(255), `last_sign_in_ip` varchar(255), `name` varchar(255), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB

Tasks: TOP => db:migrate
(See full trace by running task with --trace)

我正在学习教程并且很难理解为什么会这样。谁能解释一下发生了什么?

10 个答案:

答案 0 :(得分:62)

create_users迁移(APP_ROOT / db / migrate / ..)中,在drop_table :users之前添加create_table :users并运行rake db:migrate。它将在重新创建之前删除users表。您可以在运行此迁移后删除该行代码,以便以后不会出现错误。如果您没有对数据库的UI访问权限(例如,在heroku上),这只是一个小修复。

答案 1 :(得分:22)

您需要从sql lite控制台中删除该表(您将丢失其中包含的所有数据)

  1. 访问sql lite控制台,输入终端
    mysql <DB NAME HERE>

  2. 掉落表(不要忘记最后的; (分号))
    drop table table_name;

  3. 再次运行 db:migrate
    bin/rake db:migrate

  4. 希望它有所帮助,它对我有用

答案 2 :(得分:14)

如果您想安全玩耍并且不想丢失任何数据,那么您可以检查数据库中是否存在该表。

class DeviseCreateUsers < ActiveRecord::Migration
  def up
    if table_exists?(:users)
      # update or modify columns of users table here accordingly.
    else
      # create table and dump the schema here
    end
  end

  def down
    # same approach goes here but in the reverse logic
  end
end

答案 3 :(得分:12)

迁移正在尝试创建数据库中已存在的表。

尝试从数据库中删除用户表。您的迁移过程出了问题。您还应该将schema.rb版本与db / migrate / * .rb文件进行比较。

<强>澄清:

许多SO用户似乎不同意我的回复,因为他们认为这不准确或不推荐。

删除表总是具有破坏性,我认为每个人都理解这一点。

我应该提到add_column,因为该表是在另一个迁移文件中创建的。

答案 4 :(得分:10)

如果您知道数据库已正确创建,则只需注释掉迁移代码的创建部分即可。例如:

Class ActsAsVotableMigration < ActiveRecord::Migration
  def self.up
#    create_table :votes do |t|
#
#      t.references :votable, :polymorphic => true
#      t.references :voter, :polymorphic => true
#
#      t.boolean :vote_flag
#
#      t.timestamps
#    end
#
#    add_index :votes, [:votable_id, :votable_type]
#    add_index :votes, [:voter_id, :voter_type]
  end

  def self.down
    drop_table :votes
  end
end

如果表已创建,但后来的命令由于某种原因未完成,您可以保留后面的选项,例如:

Class ActsAsVotableMigration < ActiveRecord::Migration
  def self.up
#    create_table :votes do |t|
#
#      t.references :votable, :polymorphic => true
#      t.references :voter, :polymorphic => true
#
#      t.boolean :vote_flag
#
#      t.timestamps
#    end

    add_index :votes, [:votable_id, :votable_type]
    add_index :votes, [:voter_id, :voter_type]
  end

  def self.down
    drop_table :votes
  end
end

如果您的数据库中没有任何重要数据要保留,那么您可以让它删除表和所有数据并重新创建。例如(注意“drop_table:votes”,在self.up中):

class ActsAsVotableMigration < ActiveRecord::Migration
  def self.up
    drop_table :votes
    create_table :votes do |t|

      t.references :votable, :polymorphic => true
      t.references :voter, :polymorphic => true

      t.boolean :vote_flag

      t.timestamps
    end

    add_index :votes, [:votable_id, :votable_type]
    add_index :votes, [:voter_id, :voter_type]
  end

  def self.down
    drop_table :votes
  end
end

答案 5 :(得分:5)

不要删除表格。数据&gt;迁移!

数据库的版本已经反映了导致错误的迁移尝试添加的更改。换句话说,如果可以跳过迁移,那么一切都会好的。检查db_schema_migrations表并尝试插入错误迁移的版本(e.x,20151004034808)。在我的情况下,这导致后续迁移完美执行,一切似乎都很好。

仍不确定导致此问题的原因。

答案 6 :(得分:1)

我认为这是rails中mysql的一个独特或更常见的问题,可能与mysql2 gem本身有关。

我知道这是因为我刚从sqlite切换到mysql并且系统地开始解决这个问题。

在我的情况下,我只是注释掉已经运行的代码并再次运行迁移(我没有添加更多细节,因为它看起来像我上面的那个人那样)。

答案 7 :(得分:1)

尝试将Devise身份验证添加到现有Users表时,我遇到了类似的问题。

我的解决方案:我发现我有两个迁移文件,都试图创建Users表。因此,我没有删除表(可能不是形成的最佳习惯),而是注释掉了创建Users表的第一个(原始)迁移文件,然后按原样离开了Devise迁移文件。重新运行迁移,它工作正常。

事实证明,Devise文件没有导致问题;我可以看到它正在“更改”表,而不是“创建它”,这意味着即使没有设计安装,db:migrate也可能导致同样的问题(尽管我没有测试过这个)。

答案 8 :(得分:1)

如果您想保留数据重命名表,但要在迁移中执行以节省时间,然后在迁移完成后将其删除。

放置在迁移文件的向上部分的顶部。

rename_table :users, :users2

答案 9 :(得分:0)

如果您的应用是新应用,并且您不关心数据库中的数据,只需:

rake db:reset