2012-04-12 14 views
1

Ich habe 2 Datenbanken Unter der Annahme, main und temp, ich habe eine Klasse Active Entry, die in main zu einem entries Tabelle entspricht, wie kann ich eine ähnliche Tabelle in temp erstellen.Wie kann ich eine Tabelle in einer anderen Datenbank in Rails mit ActiveRecord duplizieren?

Der erste Stich ist Entry.connection.execute('show create table #{Entry.table_name}') verwenden und gegen eine andere Tabelle aufrufen. (funktioniert, wenn main und temp die gleiche Art von Datenbank sind).

Gibt es einen schöneren Weg, es zu tun? Vorzugsweise eine, die nicht das Lesen von & Aufruf von "create table" -Ausdrücken beinhaltet.

Zum Beispiel scheint etwas mit ActiveRecord :: Schema.define am besten zu sein. Aber ich bin mir nicht sicher, was ich genau machen soll.

Danke.

+0

Sie erkennen Sie, dass jede Methode schließlich nennen 'show table' schaffen, nicht wahr? Willst du es einfach nicht selbst nennen? :) –

+0

@SergioTulentsev Ich gehe davon aus, dass ActiveRecord-Adapter mit feinen Unterschieden in der create table-Syntax für mich umgehen. z.B. Wenn eine Tabelle MySQL und die andere SQLite ist. – z5h

Antwort

2

Nach dem schnellen googlen fand ich keine fertige Methode, um dies ohne rohe SQL zu erreichen. Sie können jedoch Ihre eigene Lösung erstellen, indem Sie nachahmen, was annotate_models tut.

Ein Stück von https://github.com/ctran/annotate_models/blob/master/lib/annotate/annotate_models.rb

# Use the column information in an ActiveRecord class 
# to create a comment block containing a line for 
# each column. The line contains the column name, 
# the type (and length), and any optional attributes 
def get_schema_info(klass, header, options = {}) 
    info = "# #{header}\n#\n" 
    info << "# Table name: #{klass.table_name}\n#\n" 

    max_size = klass.column_names.collect{|name| name.size}.max + 1 
    klass.columns.each do |col| 
    attrs = [] 
    attrs << "default(#{quote(col.default)})" unless col.default.nil? 
    attrs << "not null" unless col.null 
    attrs << "primary key" if col.name == klass.primary_key 

    col_type = col.type.to_s 
    if col_type == "decimal" 
     col_type << "(#{col.precision}, #{col.scale})" 

Auch Sie könnten lesen wollen, was ActiveRecord Migrations Guide zu bieten hat.

ActiveRecord::Schema.define(:version => 20080906171750) do 
    create_table "authors", :force => true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 
end 

Diese Datei wird durch Überprüfen der Datenbank und mit dem Ausdruck seiner Struktur mit create_table, add_index, und so weiter geschaffen. Da dies datenbankunabhängig ist, könnte es in jede Datenbank geladen werden, die Active Record unterstützt. Dies könnte sehr nützlich sein, wenn Sie eine Anwendung verteilen möchten, die in der Lage ist, gegen mehrere Datenbanken zu laufen.

Es gibt jedoch einen Kompromiss: db/schema.rb kann keine datenbankspezifischen Elemente wie Fremdschlüsseleinschränkungen, Trigger oder gespeicherte Prozeduren ausdrücken. Während einer Migration können Sie benutzerdefinierte SQL-Anweisungen ausführen, der Schema-Dumper kann diese Anweisungen nicht aus der Datenbank wiederherstellen. Wenn Sie Funktionen wie diese verwenden, sollten Sie das Schemaformat auf Folgendes setzen: sql.

Anstatt den Schema-Dumper von Active Record zu verwenden, wird die Struktur der Datenbank mit einem für die Datenbank spezifischen Tool (über die Task db: structure: dump Rake) in db/structure.sql ausgegeben. Zum Beispiel wird für das PostgreSQL-RDBMS das Dienstprogramm pg_dump verwendet. Für MySQL enthält diese Datei die Ausgabe von SHOW CREATE TABLE für die verschiedenen Tabellen. Das Laden dieser Schemas ist einfach eine Frage der Ausführung der SQL-Anweisungen, die sie enthalten. Per Definition wird dadurch eine perfekte Kopie der Datenbankstruktur erstellt. Die Verwendung des Schemas sql schema verhindert jedoch, dass das Schema in ein anderes RDBMS geladen wird als das, das zum Erstellen verwendet wurde.

1

Wenn Sie nur von einer Datenbank in eine andere verschieben, verwenden Juwel ‚yaml_db‘

+0

Sieht interessant aus. Aber die Yaml-Datei als Zwischenhändler wird nicht benötigt. Vielen Dank. – z5h

Verwandte Themen