Rails DB-Migration - Wie lösche ich eine Tabelle?

507

Ich habe eine Tabelle hinzugefügt, von der ich dachte, dass ich sie brauchen würde, aber jetzt habe ich nicht mehr vor, sie zu verwenden. Wie soll ich diese Tabelle entfernen?

Ich habe bereits Migrationen ausgeführt, daher befindet sich die Tabelle in meiner Datenbank. Ich denkerails generate migration sollte damit umgehen können, aber ich habe noch nicht herausgefunden, wie.

Ich habe es versucht:

rails generate migration drop_tablename

aber das hat gerade eine leere Migration erzeugt.

Was ist der "offizielle" Weg, um einen Tisch in Rails abzulegen?

Jason Whitehorn
quelle
1
Da rails generate migrationes Befehlszeilenoptionen zum Generieren von Migrationscode zum Erstellen von Tabellen, Hinzufügen oder Ändern von Spalten usw. gibt, wäre es schön, wenn es auch eine Option zum Löschen einer Tabelle hätte - aber nicht. Sicher, das Schreiben des upTeils ist einfach - rufen Sie einfach auf drop_table-, aber das downTeil, das die Tabelle erneut generiert, ist möglicherweise nicht immer so einfach, insbesondere wenn das Schema der betreffenden Tabelle nach der ersten Erstellung durch Migrationen geändert wurde. Vielleicht sollte jemand den Entwicklern von Rails vorschlagen, dass das Hinzufügen einer solchen Option eine gute Idee wäre.
Teemu Leisti
3
@TeemuLeisti Wie wäre es, wenn Sie einfach die aktuelle Tabellendefinition aus schema.rb kopieren und einfügen? Ich mache es die ganze Zeit so ...
Jasoares
1
@ João Soares: OK, ich denke das funktioniert. Es wäre jedoch schön, wenn der Prozess automatisiert werden könnte, sodass Sie einfach einen rakeBefehl zur Erstellung der Migration mit dem Namen einer Tabelle als Parameter eingeben könnten , der die erforderlichen Funktionen upund downFunktionen erzeugt.
Teemu Leisti

Antworten:

647

Sie können die Migration nicht immer einfach generieren, um bereits den gewünschten Code zu erhalten. Sie können eine leere Migration erstellen und diese dann mit dem benötigten Code füllen.

Informationen zum Ausführen verschiedener Aufgaben in einer Migration finden Sie hier:

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

Insbesondere können Sie sehen, wie Sie eine Tabelle mit dem folgenden Ansatz löschen:

drop_table :table_name
Pete
quelle
3
Das hat auch bei mir funktioniert. Bei vollständigen Migrationen (Installation von Grund auf neu) wird die Tabelle jetzt zuerst erstellt und später wieder gelöscht. Ist es sicher, die Migrationen zum Erstellen und Löschen später zu entfernen?
berkes
2
Gibt es hier eine Ansicht darüber, ob es besser ist, Tabellen zu löschen oder zu einem vorherigen Datenbankschema zurückzukehren?
William erzählt
3
Wenn Sie mit dem Tisch fertig sind und nicht mehr vorhaben, ihn zu verwenden, würde ich sagen, lassen Sie ihn einfach fallen. Es ist besser, es loszuwerden, wenn es nicht verwendet wird.
Pete
6
Die Antwort von @BederAcostaBorges ist selbsterklärender und genauer
onerinas
2
Wie entferne ich auch alle Fremdschlüssel? In anderen Tabellen befinden sich Spalten, die auf die zu löschende Tabelle verweisen.
Martin Konicek
352

Generieren Sie zunächst eine leere Migration mit einem beliebigen Namen. Es ist wichtig, dies auf diese Weise zu tun, da das entsprechende Datum erstellt wird.

rails generate migration DropProductsTable

Dadurch wird eine .rb-Datei in / db / migrate / like 20111015185025_drop_products_table.rb generiert

Bearbeiten Sie nun diese Datei so, dass sie folgendermaßen aussieht:

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

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

Das einzige was ich hinzufügte war drop_table :productsund raise ActiveRecord::IrreversibleMigration.

Dann renne rake db:migrateund es wird den Tisch für dich fallen lassen.

Brandon O'Rourke
quelle
14
Eine Abwärtsmigration sollte verwendet werden, um die abgelegte Tabelle neu zu erstellen.
fflyer05
1
Diese Migration konnte selbst in der Entwicklung niemals rückgängig gemacht werden. Wäre es besser, die Abwärtsmigration einfach leer zu lassen?
Mhriess
1
Dies ist die bessere Antwort + Fflyer Kommentar
Zack Shapiro
2
@mjnissim und fflyer05 sind korrekt. Um seltsame Dinge zu vermeiden, sollten Sie die Tabelle in der Down-Methode neu erstellen.
Sebastialonso
4
Durch das Löschen einer Tabelle werden alle Daten gelöscht. Wenn Sie sie in der downMethode neu erstellen, werden sie nicht wiederhergestellt, sodass es sich nicht um ein ordnungsgemäßes Rollback handelt. Es ist besser, klar anzuzeigen, dass die Migration irreversibel ist, als ein falsches Gefühl zu geben, von dem sie wiederhergestellt werden kann.
Vivi
314

Schreiben Sie Ihre Migration manuell. ZB laufen rails g migration DropUsers.

Was den Code der Migration betrifft, zitiere ich nur die Post Rails Migration Checkliste von Maxwell Holder

BAD - läuft rake db:migrateund wird dann rake db:rollbackscheitern

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

GUT - zeigt die Absicht, dass Migration nicht reversibel sein sollte

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

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

BESSER - ist eigentlich reversibel

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end
Beder Acosta Borges
quelle
schema.rbVergessen Sie beim Ausschneiden und Einfügen in den Block nicht, auch nach schema.rbFremdschlüsseln zu suchen . drop_tablet.foreign_key "other_table"
Fügen Sie
197

Während die hier gegebenen Antworten richtig funktionieren, wollte ich etwas "Unkomplizierteres", das ich hier gefunden habe: link Geben Sie zuerst die Rails-Konsole ein:

$rails console

Dann geben Sie einfach Folgendes ein:

ActiveRecord::Migration.drop_table(:table_name)

Und fertig, für mich gearbeitet!

lllllll
quelle
Das Modell ist noch da, bis Sie laufenrails destroy model User
gm2008
2
Führen Sie dies nur aus, wenn Sie die Tabelle endgültig entfernen möchten. Rails wird diesen Rückgang nicht bemerken. Die Migration ist nach Ausführung dieses Befehls unterbrochen. Kann nicht ERSTELLEN, TROPFEN ... ETC. FEHLER SQLite3 :: SQLException: keine solche Tabelle: Rückstellungen: DROP TABLE "sometable"
zee
36

Sie müssen eine neue Migrationsdatei mit dem folgenden Befehl erstellen

rails generate migration drop_table_xyz

und schreibe drop_table Code in neu generierte Migrationsdatei (db / migration / xxxxxxx_drop_table_xyz) wie

drop_table :tablename

Oder wenn Sie eine Tabelle ohne Migration löschen möchten, öffnen Sie einfach die Rails-Konsole von

$ rails c

und führen Sie den folgenden Befehl aus

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

oder Sie können einen vereinfachten Befehl verwenden

ActiveRecord::Migration.drop_table(:table_name)
Shahzad Tariq
quelle
21
  1. Schienen g Migration drop_users
  2. Bearbeiten Sie die Migration
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
  1. Rechen db: migrieren
Aashish Saini
quelle
13

Ich denke, um vollständig "offiziell" zu sein, müssten Sie eine neue Migration erstellen und drop_table in self.up einfügen. Die self.down-Methode sollte dann den gesamten Code enthalten, um die Tabelle vollständig neu zu erstellen. Vermutlich könnte dieser Code zum Zeitpunkt der Erstellung der Migration nur aus schema.rb entnommen werden.

Es scheint ein wenig seltsam, Code einzugeben, um eine Tabelle zu erstellen, von der Sie wissen, dass Sie sie nicht mehr benötigen, aber das würde den gesamten Migrationscode vollständig und "offiziell" halten, oder?

Ich habe das nur für einen Tisch gemacht, den ich fallen lassen musste, aber ehrlich gesagt habe ich das "down" nicht getestet und bin mir nicht sicher, warum ich es tun würde.

Francis Potter
quelle
1
Seltsam, aber es sieht so aus, als müsste ich das auch tun.
DigitalWestie
7
Oder Sie können einfach: raise ActiveRecord::IrreversibleMigrationin der self.down-Methode verwenden, sodass Sie sich mindestens einen Fehler / Hinweis geben, wenn Sie jemals versuchen, einen Rollback durchzuführen.
Steph Rose
1
Ich würde das Down testen, nur weil ich sonst ungetesteten Code in mein Projekt einführe. Wie kann ich die Up-Methode der ursprünglichen Migration wiederverwenden? Ich habe versucht CreateMyTable.upund ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)wo X die Migration ist, die die Tabelle ursprünglich erstellt hat, aber keine funktioniert - in beiden Ansätzen prüft AR zuerst, ob die Migration bereits angewendet wurde, und überspringt sie stillschweigend, wenn dies der Fall ist. `
Isaac Betesh
12

Sie können einfach einen Tisch von der Rails-Konsole ablegen. Öffnen Sie zuerst die Konsole

$ rails c

Fügen Sie dann diesen Befehl in die Konsole ein

ActiveRecord::Migration.drop_table(:table_name)

Ersetzen Sie tabellenname durch die Tabelle, die Sie löschen möchten.

Sie können die Tabelle auch direkt vom Terminal aus löschen. Geben Sie einfach in das Stammverzeichnis Ihrer Anwendung ein und führen Sie diesen Befehl aus

$ rails runner "Util::Table.clobber 'table_name'"
Farzpal Singh
quelle
10

Der einfache und offizielle Weg wäre folgender:

  rails g migration drop_tablename

Gehen Sie nun zu Ihrer Datenbank / migrate und suchen Sie nach Ihrer Datei, die den Dateinamen drop_tablename enthält, und bearbeiten Sie diese.

    def change
      drop_table :table_name
    end

Dann musst du rennen

    rake db:migrate 

auf Ihrer Konsole.

Mahesh Mesta
quelle
9

Sie können eine Migration wie im Handbuch beschrieben zurücksetzen:

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

Eine Migration generieren:

rails generate migration revert_create_tablename

Schreiben Sie die Migration:

require_relative '20121212123456_create_tablename'

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

Auf diese Weise können Sie auch ein Rollback durchführen und die Migration rückgängig machen

Matheus Silva
quelle
8

Alternative zum Auslösen einer Ausnahme oder zum Versuch, eine jetzt leere Tabelle neu zu erstellen - während das Zurücksetzen, Wiederherstellen usw. der Migration weiterhin aktiviert ist -

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

Ich konnte es nicht mit dem Migrationsskript zum Laufen bringen, also habe ich diese Lösung weiterentwickelt. Geben Sie die Rails-Konsole über das Terminal ein:

rails c

Art

ActiveRecord::Migration.drop_table(:tablename)

Es funktioniert gut für mich. Dadurch wird die vorherige Tabelle entfernt. Vergiss nicht zu rennen

rails db:migrate
Srikanth V.
quelle
7

Öffnen Sie Ihre Schienenkonsole

ActiveRecord::Base.connection.execute("drop table table_name")
manish nautiyal
quelle
4

ActiveRecord::Base.connection.drop_table :table_name

nhegroj
quelle
2

Ich musste unsere Migrationsskripte zusammen mit den Tabellen selbst löschen ...

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

vom Terminalfenster ausführen:

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

oder

$ rails runner "Util::Table.clobber_all"
Aaron Henderson
quelle
1

Der beste Weg, den Sie tun können, ist

rails g migration Drop_table_Users

Führen Sie dann die folgenden Schritte aus

rake db:migrate
Anoob K Bava
quelle
1

Lauf

rake db:migrate:down VERSION=<version>

Wo <version> ist die Versionsnummer Ihrer Migrationsdatei, die Sie zurücksetzen möchten?

Beispiel:-

rake db:migrate:down VERSION=3846656238
Rankit Ranjan
quelle
1

wenn jemand sucht, wie es in SQL geht.

Typ rails dbconsolevom Terminal

Passwort eingeben

In der Konsole tun

USE db_name;

DROP TABLE table_name;

exit

Bitte vergessen Sie nicht, die Migrationsdatei und die Tabellenstruktur aus dem Schema zu entfernen

Shan
quelle
Sie können es auch öffnen, indem Sie einfachrails db
ARK
0

Wenn Sie eine bestimmte Tabelle löschen möchten, können Sie dies tun

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

Andernfalls können Sie dies tun, wenn Sie Ihre gesamte Datenbank löschen möchten

$rails db:drop
Nicollas
quelle
-1

Tabelle / Migration löschen

Ausführen: - $ Rails generieren Migration DropTablename

exp: - $ Rails generieren Migration DropProducts

Pankaj Dhote
quelle
-1

Führen Sie diesen Befehl aus: -

rails g migration drop_table_name

dann:

rake db:migrate

oder wenn Sie eine MySQL-Datenbank verwenden, dann:

  1. Login mit Datenbank
  2. show databases;
  3. show tables;
  4. drop table_name;
Nitin Rakesh
quelle
3
Fügt diese Antwort der vorhandenen, akzeptierten Antwort etwas hinzu? Wenn nicht, müssen Sie dies nicht posten.
Tom Lord
1
Dies führt zu einer leeren Migration in Rails 4.2, wie bereits in der Frage selbst angegeben.
Bert Bruynooghe
Dies ist genau das, was das OP ursprünglich versucht hat ... diese Antwort sollte entfernt werden
webaholik
Das Hinzufügen einer einfachen Antwort verdient keine Ablehnung. Es ist immer noch relevant, denke ich. Seien Sie bitte freundlich zu neueren Benutzern.
ARK
-2

Wenn Sie die Tabelle aus dem Schema löschen möchten, führen Sie die folgende Operation aus:

rails db:rollback
iamnair
quelle