2016-07-04 93 views
1

升級到Rails 5.0,從4.2我收到以下錯誤後:Ruby on Rails的5.0升級與遷移用戶表衝突

PGError: ERROR: column 「email」 of relation 「users」 already exists

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

PG::DuplicateColumn: ERROR: column "email" of relation "users" already exists 
: ALTER TABLE "users" ADD "email" character varying DEFAULT '' NOT NULL 
/Users/my_username/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `async_exec' 
/Users/my_username/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `block in execute' 

閱讀下列兩個堆棧溢出的帖子後

Devise migration on existing model

我的問題是哪個解決與用戶選項卡發生數據庫衝突的最佳方法樂?

最好是編輯現有的遷移文件,如20160703164716 AddDeviseToUsers遷移,還是建議進行新的遷移?

什麼是進行新遷移的命令和此遷移的最佳名稱,以防止在我的開發和基於Heroku的生產環境中發生數據庫衝突?

def self.up 
    change_table(:users) do |t| 
    t.recoverable 
    t.trackable 
    # rememberable uses remember_token, but this field is different 
    t.rename :remember_token_expires_at, :remember_created_at 
    # these fields are named differently in devise 
    t.rename :crypted_password, :encrypted_password 
    end 
end 

以上是從第二篇文章中建議的建議代碼。

你會如何利用這段代碼並從中做出新的遷移?

研究遷移後,我已經做了以下遷移:

rails g migration change_data_type_for_users 

生成,我根據我的理解上述錯誤進行提示在用戶領域修復編輯的新移民。新的遷移代碼:

class ChangeDataTypeForUsers < ActiveRecord::Migration[5.0] 
    def change 
    change_table(:users) do |t| 
     t.string :email,    :null => false, :default => "" 
    end 
end 

運行rails db:migrate後收到相同的錯誤。我究竟做錯了什麼?我現在應該回滾還是編輯新遷移?

我已經找到了這個堆棧溢出文章。 (Rails 4 Ruby 2.00 Devise migration on existing User Model fails) 這是正確的道路嗎?將刪除數據庫刪除所有的數據庫數據?

另一個發現這裏導致相信如果執行rake db:reset會破壞我的數據庫中的數據。這樣做是否重新創建數據庫?目前還不清楚,從後面的文章看來,如果所有的數據都被破壞,將會非常有害。我們只想修復一個表中的一個字段。

Difference between rake db:migrate db:reset and db:schema:load

我真的想回答我的問題所以也許這種模式使得一些區別就是除了似乎已經被ActiveAdmin創建的用戶模式:

class AdminUser < ApplicationRecord 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, 
     :recoverable, :rememberable, :trackable, :validatable 
end 
+0

當你從錯誤信息看,「問題」是您要添加電子郵件列,但它已存在於您的用戶表中。遷移是好的,似乎問題在於數據庫版本(實際上已包括電子郵件列)和遷移的不同步。嘗試重置數據庫(以防您沒有任何敏感數據)。 –

+0

Paul,非常感謝。不幸的是,我有敏感的數據,這是恐懼或重置分貝。有沒有辦法回到這一列,並通過命令行刪除它?我發現很多鏈接來重置數據庫(http://stackoverflow.com/questions/10301794/difference-between-rake-dbmigrate-dbreset-and-dbschemaload),但我擔心數據庫中的其他部分的數據這是敏感的。 – March

+0

你可以刪除列,是的。運行'rails db',然後你得到你的數據庫控制檯。讀取您的數據庫引擎語法以更改表並刪除列(除非它是sqllite) –

回答

1

在你的情況下,記住你正在試圖改變數據庫中存在的列,就像你正在創建一個新的那樣。

t.string :email, :null => false, :default => "" 

,您可以更改該行

t.change :email, :string, :null => false, :default => "" 

您塊的內部,知道「T」是你的用戶表

+0

這工作謝謝@保羅布拉諾夫和@xploshioOn! – March