2010-10-26 78 views
405

我添加了一張我認爲需要的表格,但現在不再計劃使用它了。我應該如何移除該表格?Rails數據庫遷移 - 如何刪除表?

我已經運行遷移,所以表在我的數據庫中。我圖rails generate migration應該能夠處理這個,但我還沒有想出如何。

我已經試過:
rails generate migration drop_tablename
但只是產生一個空遷移。

什麼是在Rails中放置表的「官方」方法?

+0

由於'軌道生成migration'具有命令行選項用於生成遷移代碼創建表格,添加或更改列等等,如果它也有一個選項可以放置一個表格 - 但它不會。當然,編寫'up'部分很簡單 - 只需調用'drop_table' - 但是再次生成表的'down'部分可能並不總是那麼簡單,特別是如果所討論的表的模式已經改變通過在其初始創建之後進行遷移。也許有人應該向Rails的開發人員建議添加這樣的選項將是一個好主意。 – 2012-09-12 12:14:09

+3

@TeemuLeisti如何複製和粘貼schema.rb中的當前表定義?我一直這樣做... – jasoares 2013-08-31 17:22:12

+1

@JoãoSoares:好的,我猜這是有效的。然而,如果這個過程是自動化的,那麼這樣會很好,所以你可以給一個'rake'遷移創建命令,把一個表的名字作爲一個參數,產生所需的'up'和'down'功能。 – 2013-09-02 09:08:35

回答

537

您不會總是能夠簡單地生成遷移以獲得您想要的代碼。你可以創建一個空的遷移,然後用你需要的代碼填充它。

您可以找到有關如何在遷移這裏完成不同任務的信息:

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

更具體地說,你可以看到如何使用以下方法來刪除表:

drop_table :table_name 
+2

這也適用於我。但是在完全遷移(從頭開始安裝)時,表格現在將首先創建,然後再次刪除。是否可以安全地刪除創建和刪除路上的遷移? – berkes 2011-01-17 20:04:22

+1

如果沒有其他遷移使用該表(添加/刪除列,調整列屬性等),那麼它可能不會損害任何操作來刪除創建/刪除遷移。不過,我不確定刪除它們會爲您帶來什麼顯着的改進。是否有某些特定的原因會導致您將其刪除? – Pete 2011-01-19 00:52:12

+1

在這裏可以查看是否最好刪除表或恢復到以前的數據庫模式? – 2012-05-11 16:23:25

12

我認爲,要完全「正式」,您需要創建一個新的遷移,並將drop_table放在self.up中。 self.down方法應該包含所有代碼來完整地重新創建表。假設代碼可以在創建遷移時從schema.rb中獲取。

看起來有點奇怪,爲了創建一個表格,你知道你不再需要這個表格了,但是這樣可以保持所有的遷移代碼的完整性和「官方」,對吧?

我只是做了一個我需要放棄的表,但老實說,沒有測試「下」,不知道爲什麼我會。

+1

奇怪但是看起來我也必須這樣做。 – digitalWestie 2011-07-12 15:20:06

+7

或者你也可以使用:在self.down方法中'raise ActiveRecord :: IrreversibleMigration',這樣你至少給你自己一個錯誤/通知,如果你試過回滾。 – 2012-03-14 15:55:55

+1

我會測試下來,只是因爲否則我將未經測試的代碼引入到我的項目中。我如何重新使用原始遷移的啓動方法?我已經嘗試過'CreateMyTable.up'和'ActiveRecord :: Migrator.run(:up,ActiveRecord :: Migrator.migrations_paths,X)',其中X是最初創建表的遷移,但兩者都不起作用,AR首先檢查是否已經應用了遷移,如果存在,則默默跳過。 ' – 2013-06-05 14:45:52

314

首先用任何你想要的名字生成一個空的遷移。這樣做很重要,因爲它會創建適當的日期。

rails generate migration DropProductsTable 

這將在/ DB /遷移/像20111015185025_drop_products_table.rb

現在修改這個文件的.rb文件看起來像這樣:

class DropProductsTable < ActiveRecord::Migration 
    def up 
    drop_table :products 
    end 

    def down 
    raise ActiveRecord::IrreversibleMigration 
    end 
end 

我添加的唯一的事情就是drop_table :productsraise ActiveRecord::IrreversibleMigration

然後運行rake db:migrate,它會爲你放下桌子。

+14

或者你可以使用上面相同的代碼,只有在'down'方法中,把代碼重新創建如'create_table:products'等表。但無論如何,我覺得這個答案更全面和有用比接受的要好。 – mjnissim 2013-11-22 21:50:13

+10

應該使用向下遷移來重新創建要刪除的表。 – fflyer05 2014-01-09 01:34:44

+1

即使在開發中,此遷移也永遠無法回滾。將下移遷留空白會更好嗎? – mhriess 2014-04-04 17:07:19

158

雖然這裏提供的答案正常工作,我想要的東西多一點「簡單」,我在這裏找到:link 首先進入軌道控制檯:

$rails console 

然後只需鍵入:

ActiveRecord::Migration.drop_table(:users) 

其中:users是表名。做完了,爲我工作!

+1

這不會創建遷移。它只是使用遷移類刪除表。 Asker希望*創建一個遷移*來刪除表。 – 2013-02-28 18:56:27

+11

@GrantBirchmeier:我明確同意,這既不是_official_也不是_best_的方式來放棄表格。不過,我相信提問者並沒有特別注意創建一個可以刪除表的遷移。他/她從字面上首先要求提供一種「刪除桌子的方法」,在那裏我可以使用我的答案。後一種方式是放棄桌子,我的答案根本不是一個非常值得推薦的選擇,因爲移民更爲合適。 – lllllll 2013-03-01 07:54:57

+0

HI vint-i-vuit如果我不小心刪除了錯誤的表格。我如何反轉它?目前使用你的方法,但不小心丟掉了錯誤的表格。 – BC2 2014-06-23 19:14:45

8

打開你從導軌終端窗口中運行控制檯

ActiveRecord::Base.connection.execute("drop table table_name") 
2

我需要與表本身一起刪除我們的遷移腳本...

class Util::Table < ActiveRecord::Migration 

def self.clobber(table_name) 
    # drop the table 
    if ActiveRecord::Base.connection.table_exists? table_name 
     puts "\n== " + table_name.upcase.cyan + " ! " 
      << Time.now.strftime("%H:%M:%S").yellow 
     drop_table table_name 
    end 

    # locate any existing migrations for a table and delete them 
    base_folder = File.join(Rails.root.to_s, 'db', 'migrate') 
    Dir[File.join(base_folder, '**', '*.rb')].each do |file| 
     if file =~ /create_#{table_name}.rb/ 
     puts "== deleting migration: " + file.cyan + " ! " 
      << Time.now.strftime("%H:%M:%S").yellow 
     FileUtils.rm_rf(file) 
     break 
     end 
    end 
    end 

    def self.clobber_all 
    # delete every table in the db, along with every corresponding migration 
    ActiveRecord::Base.connection.tables.each {|t| clobber t} 
    end 

end 

$ rails runner "Util::Table.clobber 'your_table_name'" 

$ rails runner "Util::Table.clobber_all" 
4

ActiveRecord::Base.connection.drop_table :table_name

+0

你在ActiveRecord和Base之間缺少一個':'符號 – 2014-11-14 16:08:31

33

您需要使用在新生成的遷移文件(DB /遷移/ xxxxxxx_drop_table_xyz)像

drop_table :tablename 
創建一個新的遷移文件以下命令

rails generate migration drop_table_xyz 

,寫drop_table代碼

或者,如果您想在不遷移的情況下放置桌子,只需通過

$ rails c 

,並執行以下命令

ActiveRecord::Base.connection.execute("drop table table_name") 

,或者您可以使用更簡單的命令

ActiveRecord::Migration.drop_table(:table_name) 
+9

不挑剔,但你對這個問題晚了5年並且答案你提供的已被多次提及過。 – 2015-05-28 19:15:23

+2

@ jason-whitehorn 5年後,但是最好的總結 – Abel 2016-12-07 03:52:09

240

手動編寫遷移。例如。運行rails g migration DropUsers

至於遷移的代碼,我只是要報價麥克斯韋持有人的職位Rails Migration Checklist

BAD - 運行rake db:migrate然後rake db:rollback將失敗

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

GOOD - 揭示意圖,移民不應該可逆

class DropUsers < ActiveRecord::Migration 
    def up 
    drop_table :users 
    end 

    def down 
    fail ActiveRecord::IrreversibleMigration 
    end 
end 

BETTER - 實際上是可逆的

class DropUsers < ActiveRecord::Migration 
    def change 
    drop_table :users do |t| 
     t.string :email, null: false 
     t.timestamps null: false 
    end 
    end 
end 
+0

請按照文檔:http://guides.rubyonrails.org/active_record_migrations.html#using-reversible – zx1986 2016-04-12 04:14:19

+0

回滾你的「壞」代碼引發「爲了避免錯誤,只有給定選項或塊(可以爲空),drop_table纔是可逆的。「我認爲這比失敗ActiveRecord :: IrreversibleMigration提供的錯誤更有用嗎? Rails 4.1.6 – 2016-08-12 23:04:33

+1

@儘管我明白你的意思,但我仍然更喜歡將「GOOD」遷移到「BAD」遷移,因爲它明確指出沒有一些手動工作就不會返回。 如果你喜歡的說明文字,你可以用 它添加到例外'失敗的ActiveRecord :: IrreversibleMigration,「爲了避免失誤,如果給定的選項或塊(可以爲空)drop_table僅僅是可逆的。」' 請參閱[Active Record Migrations](http://api.rubyonrails.org/classes/ActiveRecord/Migration.html#class-ActiveRecord::Migration-label-Irreversible+transformations) – 2016-08-18 13:14:17

17
  1. 導軌克遷移drop_users
  2. 編輯遷移
class DropUsers < ActiveRecord::Migration 
     def change 
     drop_table :users do |t| 
      t.string :name 
      t.timestamps 
     end 
     end 
    end 
  • 耙分貝:遷移
  • +0

    這是一個很好的答案,因爲它提供了可逆遷移。其他答案會丟棄表,但如果您嘗試回滾,則此答案提供了回滾功能。 – 2017-03-23 09:17:19

    1

    運行

    rake db:migrate:down VERSION=<version> 
    

    其中<version>是您想要恢復的遷移文件的版本號。

    例子: -

    rake db:migrate:down VERSION=3846656238 
    
    2

    你能做的最好的辦法是

    rails g migration Drop_table_Users 
    

    然後執行以下操作

    rake db:migrate 
    
    +0

    創建一個空的遷移,就像在問題中已經說明的那樣。 – 2017-04-25 09:40:58

    10

    ,你可以簡單地從鐵軌控制檯刪除表。 首先打開控制檯

    $ rails c 
    

    然後在控制檯

    ActiveRecord::Migration.drop_table(:table_name) 
    

    粘貼此命令要刪除替換表TABLE_NAME

    您也可以直接從終端下載表格。只需在您的應用程序的根目錄進入,到目前爲止,運行此命令

    $ rails runner "Util::Table.clobber 'table_name'" 
    
    +0

    然後當你稍後運行你的遷移時,你會返回表格。糟糕的想法是在遷移之外的Rails中刪除表格,因爲該架構會與遷移分離。這打破了Rails約定。 – 2017-03-23 09:18:58

    +0

    當然你也必須刪除遷移文件。如果你在本地工作,如果你的代碼在服務器上,那麼這些都是你的想法,那麼創建新的遷移文件以刪除表或者如果你是服務器專家也是好事,那麼你可以簡單地刪除遷移文件並從表中刪除表控制檯在服務器上。 – 2017-04-07 09:52:25

    3

    這不是最好的或者正確的解決方案,你能做到早期發展階段...

    發展ENV 。您可以從(db/migrate/12345.....name_of_migrated_file)刪除遷移文件。

    rake db:drop 
    rake db:create #This is unnecessary if using SQlite, but useful sometimes. 
    rake db:migrate 
    
    #or 
    rake db:migrate:reset 
    

    如果你有種子文件,只需要爲開發創建新的rake任務。

    #file: /lib/taks/db.rake 
    namespace :db do 
        desc 'Drop, create, migrate then seed the development database' 
        task database: [ 'db:drop', 'db:create', 'db:migrate', 'db:seed' ] do 
        puts 'Datebase Remigrated.' 
        end 
    end 
    
    # And you can run it. It will drop, create, migrate and seed for you. 
    rake db:database 
    
    +0

    顯然./bin/rake db:drop然後遷移工作正常。但我不知道是否不說明表等會導致任何問題。 – 2015-11-19 11:53:22

    +4

    我不能相信這有票。 – jeffdill2 2016-08-22 12:05:59

    +0

    非常糟糕的想法做到這一點。 DB不應該被視爲快餐。 ;) – 2018-01-30 04:53:00

    3

    運行以下命令: -

    $軌摹遷移drop_table_name

    則:

    $耙分貝:遷移

    ,或者如果你正在使用MySQL數據庫那麼:

    1. 用數據庫登錄
    2. show databases;
    3. 顯示錶格;
    4. drop table_name;
    +2

    這個答案是否將任何內容添加到現有的接受答案?如果沒有,就沒有必要發佈這個。 – 2016-06-17 13:27:12

    +0

    這在軌道4.2中創建了一個空的遷移,正如問題本身已經說過的那樣。 – 2017-04-25 09:40:22

    4

    簡單的和官方的方法是這樣的:

    rails g migration drop_tablename 
    

    現在去你的DB /遷移,查看您的文件,其中包含了drop_tablename作爲文件名,並進行修改對此。

    def change 
         drop_table :table_name 
        end 
    

    然後,你需要在控制檯上運行

    rake db:migrate 
    

    +1

    如果表中有外部索引,則需要執行'''drop_table:golfers,force :: cascade''' – Obromios 2017-08-28 03:17:23

    2

    替代提高異常或嘗試重新建立一個現在空表 - 同時仍然使遷移回滾,重做等 -

    def change drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users') end