2009-10-09 10 views
12

Ich möchte eine Migration, um einen Klon einer vorhandenen Tabelle zu erstellen, indem Sie einfach den Namen, einschließlich aller Indizes aus der ursprünglichen Tabelle.Wie könnten Sie eine Datenbanktabelle über die Rails-Migration klonen?

Also gibt es eine "Snapshots" -Tabelle und ich möchte "snapshots_temp" als eine exakte Kopie der Tabelle erstellen (nicht die Daten, nur das Tabellenschema, sondern einschließlich der Indizes).

Ich könnte einfach kopieren und fügen Sie den Block aus der schema.rb-Datei und manuell umbenennen.

Aber ich bin nicht sicher, wenn diese Migration angewendet wird, wenn die Definition aus schema.rb immer noch korrekt ist. Ein anderer Entwickler hat die Tabelle möglicherweise geändert, und ich möchte mein Migrationsskript nicht aktualisieren müssen.

Also, wie bekomme ich das Schema der Tabelle zur Laufzeit? Im Wesentlichen, wie "Rake Schema: Dump" Reverse Engineering der Tabelle, so kann ich das gleiche in meiner Migration tun? (aber den Tabellennamen ändern).

Antwort

21

Versuchen Sie es mit reinem SQL. Dies wird tun, was Sie wollen:

CREATE TABLE new_tbl LIKE orig_tbl; 
+0

Guter Anruf. "Verwenden Sie LIKE, um eine leere Tabelle zu erstellen, die auf der Definition einer anderen Tabelle basiert, einschließlich aller in der ursprünglichen Tabelle definierten Spaltenattribute und Indizes" http://dev.mysql.com/doc/refman/5.1/en/create-table. html –

+0

Funktioniert mit MySQL (und möglicherweise die meisten Datenbanken), aber wenn Sie Sqlite verwenden, wird es nicht funktionieren. Ich bin auf dieses Problem in der Entwicklungsumgebung gestoßen. Die Produktion ist gut (es ist MySQL). – MiniQuark

+1

Super danke. Beachten Sie, dass Ihre kopierte Tabelle die Indizes, aber keine Fremdschlüssel erhält. Sie müssen diese separat erstellen. –

4

Dies wird ausreichen. Es ist nicht perfekt, weil es keine Tabellenoptionen oder Indizes kopiert. Wenn Sie Tabellenoptionen festgelegt haben, müssen Sie diese manuell zu dieser Migration hinzufügen.

Um Indizes zu kopieren, müssen Sie eine SQL-Abfrage formulieren, um sie auszuwählen, und sie dann in neue add_index-Anweisungen verarbeiten. Das ist ein bisschen jenseits meines Wissens. Aber das funktioniert, um die Struktur zu kopieren.

class CopyTableSchema < ActiveRecord::Migration 
    def self.up 
    create_table :new_models do |t| 
     Model.columns.each do |column| 
     next if column.name == "id" # already created by create_table 
     t.send(column.type.to_sym, column.name.to_sym, :null => column.null, 
      :limit => column.limit, :default => column.default, :scale => column.scale, 
      :precision => column.precision) 
     end 
    end 

    # copy data 

    Model.all.each do |m| 
     NewModel.create m.attributes 
    end 
    end 

    def self.down 
    drop_table :new_models 
    end 
end 
+0

> es wird nicht kopiert Tabelle Optionen oder Indizes Danke, aber Indizes ist eine Voraussetzung. –

4

In Rails 4 & PostgreSQL, erstellen Sie eine neue Migration und einfügen:

ActiveRecord::Base.connection.execute("CREATE TABLE clone_table_name AS SELECT * FROM source_table_name;") 

Dieser den Klon mit der genauen Struktur der ursprünglichen Tabelle erstellen, und füllen die neue Tabelle mit alten Werten.

Weitere Informationen: http://www.postgresql.org/docs/9.0/static/sql-createtableas.html

+1

Vorsicht mit diesem, da es auch die ID-Spalte kopiert und es nicht als primäre in der neuen Tabelle festlegen wird. –

0

Kopieren Sie die Tabellen-Eintrag aus Ihren Projekten db/schema.rb direkt in Ihre Migration. Ändern Sie einfach den Tabellennamen und Ihr Gut, um zu gehen.