添加设计生成的用户表时,Rails 数据库迁移失败并出现“重复的列名:电子邮件”

Posted

技术标签:

【中文标题】添加设计生成的用户表时,Rails 数据库迁移失败并出现“重复的列名:电子邮件”【英文标题】:Rails database migration fails with "duplicate column name: email" when adding devise's generated User table 【发布时间】:2014-08-08 04:38:52 【问题描述】:

我正在安装devise。我遵循了所有必需的步骤并在此处结束:

$ rails generate devise User
$ rake db:migrate

当我运行rake db:migrate 时,出现以下错误:

$ rake db:migrate
== 20140618020442 AddDeviseToUsers: migrating =================================
-- change_table(:users)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: duplicate column name: email: ALTER TABLE "users" ADD "em
ail" varchar(255) DEFAULT '' NOT NULLc:/appname/db/migrate/20140618020442_add_d
evise_to_users.rb:5:in `block in up'
c:/appname/db/migrate/20140618020442_add_devise_to_users.rb:3:in `up'
c:in `migrate'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

我的项目具有以下数据库架构。部分devise 迁移看似成功,但尚未完成迁移。

ActiveRecord::Schema.define(version: 20140618020442) do

  create_table "listings", force: true do |t|
    t.string   "name"
    t.text     "description"
    t.decimal  "price"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
  end

  create_table "users", force: true do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

问题是什么,我该如何解决?

【问题讨论】:

看起来您已经在 user 表上创建了列 email。您可以转到设计迁移文件删除 t.string :email 行,然后再次运行 rake db:migrate 我删除了 t.string :email 行。当我现在运行 rake db:migrate 时,它​​给了我与 t.string :encrypted_pa​​ssword 行相同的错误。当我删除这个时,它会继续到下一行,依此类推...... @user3208597 你能列出你做的所有步骤吗? @user2675613 你的意思是删除这些行并运行 db:migrate 还是你的意思是我之前所做的? @user3208597 我的意思是你安装的所有步骤都设计了什么?你能发布你的迁移文件timestamp_devise_create_users.rbschema.rb 文件只是为了检查是否已经有一个用户表 【参考方案1】:

所以问题是您的数据库中已经有了 users 表。如果该表不起作用,您需要删除该表并创建一个新表,或者继续使用该表。

删除数据库不是一个好主意,但是由于您正在创建一个新应用程序(在创建用户表时),所以在您的情况下,最好删除该数据库并重新创建它(以确保一切正常)。按顺序尝试这些命令:

rake db:drop
rake db:create
rake db:migrate

它应该可以正常工作,您不需要rails generate devise User,因为您已经有了用户迁移文件

更新:

如果您不想删除数据库,则可以创建一个新的迁移文件并在那里删除您的用户表。

rails generate migration DropUsersTable

之后编辑您的迁移文件

class DropUsersTable < ActiveRecord::Migration
  def change
    drop_table :users
  end
end

然后做rake db:migrate

【讨论】:

你不一定知道这个应用是新的。谁说应用开发的第一步是创建users 表?有一些解决方案围绕必须完全删除您的数据库以及与之关联的所有数据。也许他唯一的表是listings,但他的表中可能有数千列。做最坏的准备,做最好的。鉴于他不能放弃他的整个数据集,给他一个可以解决解决方案的答案。 (是的,我喜欢你在回答中提到放弃 DB 不是一个好主意的方式......我认为你应该继续朝那个方向发展 :)) @Justin 如果您“正确”阅读了他的问题,他正在学习一个教程,这意味着他刚刚开始学习它,如果您“足够关心”并打开他为您提供的教程链接会看到他刚刚开始添加他的应用程序。我知道会有一些像你这样的“人”,这就是为什么我在回答中明确提到这不是一个好习惯,如果你注意到我还指定了为了确保你的应用程序启动并运行你可以重新创建你的数据库 @Justin 我建议它只是为了确保他的应用程序尽快启动并运行,因为我也经历了那个阶段,没有人喜欢在你刚开始的时候特别注意起来 我去了 baserails.com,看到了一些需要花钱的东西(尽管首先是免费试用),但仍然需要 CC。我希望你能理解我的评论和理由。抱歉冒犯了你。 @Justin 还有一个工作原理部分,您可以在其中查看它。我可以编辑我的答案并更改它,但你知道什么是有趣的事情,而不是“回答他的问题”,你选择只看它并否决了一个已经说明所有缺点的答案【参考方案2】:

解决方案: 1. 将所有迁移文件放在新的 archived_migrations 文件夹中的迁移文件夹中。 2. 数据库:模式:加载 3. 运行 rake db:migrate

【讨论】:

为什么要将所有迁移放在一个文件中?在一个真正的项目中,你将无法做到这一点,这与重新创建数据库一样可能会更糟:) 迁移文件在“迁移”中从一开始就在单个文件中。我忘了提到我还运行了 rake db:schema:load。这为我解决了这个问题,并且没有创建新的数据库。你能进一步解释这个问题吗? 迁移文件始终位于单个迁移文件夹中。您说您将它们全部放在一个文件中,然后运行我正在谈论的迁移文件。在实际项目中,您并不了解所有需求,并且您已经拥有一个充满数据的数据库 对不起。我的意思是我把它们都放在一个文件夹里。很抱歉造成混乱,非常感谢您为解决我的问题付出的所有努力。我很感激!

以上是关于添加设计生成的用户表时,Rails 数据库迁移失败并出现“重复的列名:电子邮件”的主要内容,如果未能解决你的问题,请参考以下文章

Rails 创建没有迁移的表

有啥方法可以不在 Rails 中生成迁移文件

在 Rails 5 中添加引用列迁移

更改列的 Rails 迁移

Rails迁移以将主键添加到现有表

在 Rails 4 中添加引用列迁移