Rails DB Migration - Jak upuścić tabelę?


506

Dodałem stół, który, jak sądzę, będzie mi potrzebny, ale już nie planuję go używać. Jak powinienem usunąć ten stół?

Już uruchomiłem migracje, więc tabela jest w mojej bazie danych. Myślę, że rails generate migrationpowinienem sobie z tym poradzić, ale nie wiem, jak to zrobić.

Próbowałem:

rails generate migration drop_tablename

ale to wygenerowało pustą migrację.

Jaki jest „oficjalny” sposób na upuszczenie stołu w Railsach?


1
Ponieważ rails generate migrationma opcje wiersza polecenia do generowania kodu migracji do tworzenia tabel, dodawania lub zmieniania kolumn itp., Byłoby miło, gdyby miał również opcję upuszczenia tabeli - ale tak nie jest. Jasne, napisanie upczęści jest proste - wystarczy wywołać drop_table- ale downczęść, ponownie generując tabelę, może nie zawsze być taka prosta, szczególnie jeśli schemat danej tabeli został zmieniony przez migracje po jej początkowym utworzeniu. Może ktoś powinien zasugerować twórcom Railsów, że dodanie takiej opcji byłoby dobrym pomysłem.
Teemu Leisti,

3
@TeemuLeisti A może po prostu skopiuj i wklej bieżącą definicję tabeli ze schema.rb? Robię to w ten sposób cały czas ...
jasoares

1
@ João Soares: OK, chyba to działa. Byłoby jednak miło, gdyby proces mógł zostać zautomatyzowany, tak aby można było po prostu wydać rakepolecenie migracji-tworzenia, z nazwą tabeli jako parametrem, która generowałaby potrzebne funkcje upi downfunkcje.
Teemu Leisti,

Odpowiedzi:


646

Nie zawsze będziesz w stanie po prostu wygenerować migrację, aby mieć już odpowiedni kod. Możesz utworzyć pustą migrację, a następnie wypełnić ją potrzebnym kodem.

Informacje na temat wykonywania różnych zadań podczas migracji można znaleźć tutaj:

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

Mówiąc dokładniej, możesz zobaczyć, jak upuścić tabelę, stosując następujące podejście:

drop_table :table_name

3
To też działało dla mnie. Ale przy pełnej migracji (instalacja od zera) tabela zostanie najpierw utworzona, a później ponownie usunięta. Czy bezpiecznie jest usunąć tworzenie i upuszczać migracje po drodze?
berkes

2
Masz tutaj pogląd na to, czy lepiej upuścić tabele, czy powrócić do poprzedniego schematu bazy danych?
William powie

3
Jeśli skończysz ze stołem i nie planujesz go więcej używać, powiedziałbym, że po prostu go upuść. Lepiej się go pozbyć, jeśli nie jest używany.
Pete

6
odpowiedź @BederAcostaBorges jest bardziej zrozumiała i dokładna
onerinas

2
Jak usunąć wszystkie klucze obce? W innych tabelach znajdują się kolumny wskazujące na upuszczanie tabeli.
Martin Konicek,

352

Najpierw wygeneruj pustą migrację o dowolnej nazwie. Ważne jest, aby zrobić to w ten sposób, ponieważ tworzy on odpowiednią datę.

rails generate migration DropProductsTable

Spowoduje to wygenerowanie pliku .rb w / db / migrate / like 20111015185025_drop_products_table.rb

Teraz edytuj ten plik, aby wyglądał tak:

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

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

Jedyne, co dodałem, to drop_table :productsi raise ActiveRecord::IrreversibleMigration.

Następnie biegnij, rake db:migratea ona upuści dla ciebie stół.


14
Do odtworzenia upuszczanej tabeli należy użyć migracji w dół.
fflyer05

1
Tej migracji nigdy nie można przywrócić, nawet w fazie rozwoju. Czy lepiej zostawić pustą migrację w dół?
mhriess

1
To jest lepsza odpowiedź + komentarz fflyera
Zack Shapiro

2
@mjnissim i fflyer05 są poprawne, aby uniknąć dziwnych rzeczy, powinieneś odtworzyć tabelę metodą down.
Sebastialonso,

4
Upuszczenie tabeli powoduje usunięcie wszystkich danych, jeśli odtworzysz ją w downmetodzie, nie odzyskasz jej, więc nie jest to właściwe wycofanie. Lepiej wyraźnie wskazać, że migracja jest nieodwracalna, niż dać fałszywe poczucie, że można ją odzyskać.
vivi

314

Napisz swoją migrację ręcznie. Np rails g migration DropUsers. Biegnij .

Jeśli chodzi o kod migracji, zacytuję post Maxwell Holder Rails Migration Checklist

ZŁE - działa, rake db:migratea następnie rake db:rollbackzawiedzie

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

DOBRY - ujawnia zamiar, aby migracja nie była odwracalna

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

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

LEPSZE - jest w rzeczywistości odwracalne

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

Jeśli wycinasz i wklejasz do bloku schema.rb, nie zapomnij również poszukać schema.rbkluczy obcych. Następnie dodaj definicję klucza obcego do drop_tablebloku, np .:t.foreign_key "other_table"
Lencho Reyes

197

Chociaż podane tutaj odpowiedzi działają poprawnie, chciałem czegoś bardziej „prostego”, znalazłem to tutaj: link Najpierw wejdź do konsoli szyn:

$rails console

Następnie wpisz:

ActiveRecord::Migration.drop_table(:table_name)

I gotowe, działało dla mnie!


Model jest nadal dostępny, dopóki nie uruchomiszrails destroy model User
gm2008

2
Uruchom to tylko, jeśli chcesz na dobre pozbyć się stołu. Szyny nie będą świadome tego spadku. Migracja jest przerywana po uruchomieniu tego polecenia. Nie można utworzyć, DROP ... ETC. BŁĄD SQLite3 :: SQLException: brak takiej tabeli: rozliczenia międzyokresowe: DROP TABLE „somable”
zee

36

Musisz utworzyć nowy plik migracji za pomocą następującego polecenia

rails generate migration drop_table_xyz

i napisz kod drop_table w nowo wygenerowanym pliku migracji (db /igration / xxxxxxx_drop_table_xyz) jak

drop_table :tablename

Lub jeśli chcesz usunąć tabelę bez migracji, po prostu otwórz konsolę szyn przez

$ rails c

i wykonaj następujące polecenie

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

lub możesz użyć bardziej uproszczonego polecenia

ActiveRecord::Migration.drop_table(:table_name)

21
  1. szyny g migracja drop_users
  2. edytuj migrację
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. rake db: migracja

13

Myślę, że aby być całkowicie „oficjalnym”, musisz utworzyć nową migrację i umieścić drop_table w self.up. Metoda self.down powinna następnie zawierać cały kod, aby odtworzyć tabelę w całości. Przypuszczalnie ten kod można pobrać z pliku schema.rb podczas tworzenia migracji.

Wydaje się to trochę dziwne, aby wprowadzić kod w celu utworzenia tabeli, o której wiesz, że już nie będziesz potrzebować, ale dzięki temu cały kod migracji będzie kompletny i „oficjalny”, prawda?

Zrobiłem to tylko dla stołu, który musiałem upuścić, ale szczerze mówiąc nie przetestowałem „upadku” i nie jestem pewien, dlaczego to zrobię.


1
Dziwne, ale wygląda na to, że będę musiał to zrobić.
digitalWestie

7
Lub możesz po prostu użyć: raise ActiveRecord::IrreversibleMigrationw metodzie self.down, abyś w LEAST dał sobie błąd / powiadomienie, jeśli kiedykolwiek spróbujesz wycofać.
Steph Rose

1
Testowałbym down tylko dlatego, że w przeciwnym razie wprowadzam do mojego projektu niesprawdzony kod. Jak mogę ponownie użyć oryginalnej metody migracji oryginalnej? Próbowałem CreateMyTable.upi ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)gdzie X to migracja, która pierwotnie utworzyła tabelę, ale żadna z nich nie działa - w obu podejściach AR najpierw sprawdza, czy migracja została już zastosowana, i cicho pomija ją, jeśli ma. `
Isaac Betesh

12

możesz po prostu upuścić stół z konsoli szyn. najpierw otwórz konsolę

$ rails c

następnie wklej to polecenie w konsoli

ActiveRecord::Migration.drop_table(:table_name)

zamień nazwa_tabeli na tabelę, którą chcesz usunąć.

możesz także upuścić tabelę bezpośrednio z terminala. wystarczy wejść do katalogu głównego aplikacji i uruchomić to polecenie

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

10

Prosty i oficjalny sposób byłby następujący:

  rails g migration drop_tablename

Teraz przejdź do db / migrate i poszukaj swojego pliku, który zawiera drop_tablename jako nazwę pliku i edytuj go do tego.

    def change
      drop_table :table_name
    end

Następnie musisz biec

    rake db:migrate 

na twojej konsoli.


9

Możesz przywrócić migrację w sposób opisany w przewodniku:

http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations

Wygeneruj migrację:

rails generate migration revert_create_tablename

Napisz migrację:

require_relative '20121212123456_create_tablename'

class RevertCreateTablename < ActiveRecord::Migration[5.0]
  def change
    revert CreateTablename    
  end
end

W ten sposób możesz także cofnąć i użyć do przywrócenia dowolnej migracji


8

Alternatywa dla zgłaszania wyjątku lub próby odtworzenia pustej tabeli - jednocześnie umożliwiając wycofanie migracji, ponawianie itp. -

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

8

Nie byłem w stanie sprawić, by działał ze skryptem migracji, więc zdecydowałem się na to rozwiązanie. Wejdź do konsoli szyn za pomocą terminala:

rails c

Rodzaj

ActiveRecord::Migration.drop_table(:tablename)

To działa dobrze dla mnie. Spowoduje to usunięcie poprzedniej tabeli. Nie zapomnij uruchomić

rails db:migrate



2

Musiałem usunąć nasze skrypty migracji oraz same tabele ...

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

z poziomu okna terminala uruchom:

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

lub

$ rails runner "Util::Table.clobber_all"

1

najlepszym sposobem na to jest

rails g migration Drop_table_Users

następnie wykonaj następujące czynności

rake db:migrate

1

Biegać

rake db:migrate:down VERSION=<version>

Gdzie <version>jest numer wersji pliku migracji, który chcesz przywrócić.

Przykład:-

rake db:migrate:down VERSION=3846656238

1

jeśli ktoś szuka jak to zrobić w SQL.

wpisz rails dbconsolez terminala

Wprowadź hasło

W konsoli zrobić

USE db_name;

DROP TABLE table_name;

exit

Nie zapomnij usunąć pliku migracji i struktury tabeli ze schematu


Możesz go również otworzyć, wpisując po prosturails db
ARK

0

jeśli chcesz upuścić określony stół, możesz to zrobić

$ rails db:migrate:up VERSION=[Here you can insert timestamp of table]

w przeciwnym razie, jeśli chcesz usunąć całą bazę danych, możesz to zrobić

$rails db:drop

-1

Upuść tabelę / migrację

uruchom: - $ szyny generują migrację DropTablename

exp: - $ tory generują migrację DropProducts


-1

Uruchom to polecenie: -

rails g migration drop_table_name

następnie:

rake db:migrate

lub jeśli korzystasz z bazy danych MySql:

  1. zaloguj się do bazy danych
  2. show databases;
  3. show tables;
  4. drop table_name;

3
Czy ta odpowiedź dodaje coś do istniejącej, zaakceptowanej odpowiedzi? Jeśli nie, nie musisz tego publikować.
Tom Lord,

1
powoduje to pustą migrację w szynach 4.2, jak już wspomniano w samym pytaniu.
bert bruynooghe

To jest dokładnie to, co OP początkowo próbował ... ta odpowiedź powinna zostać usunięta
webaholik

Dodanie prostej odpowiedzi nie zasługuje na poniżenie. Sądzę, że nadal jest istotny. Prosimy o życzliwość dla nowych użytkowników.
ARK,

-2

Jeśli chcesz usunąć tabelę ze schematu, wykonaj poniższą operację -

rails db:rollback
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.