2009-10-09 5 views
12

Я хочу, чтобы миграция создала клон существующей таблицы, просто суффиксом имени, включая все индексы из исходной таблицы.Как вы можете клонировать таблицу базы данных через миграцию Rails?

Итак, есть таблица «моментальных снимков», и я хочу создать «snapshots_temp» как точную копию таблицы (а не данные, только схему таблицы, но включая индексы).

Я мог бы просто скопировать и вставить блок из файла schema.rb и вручную переименовать его.

Но я не уверен, к моменту применения этой миграции, если определение из schema.rb будет по-прежнему точным. Другой разработчик, возможно, изменил таблицу, и я не хочу обновлять сценарий миграции.

Как я могу получить схему таблицы во время выполнения? По сути, как «rake schema: dump» реконструирует таблицу, чтобы я мог сделать то же самое в моей миграции? (но изменение имени таблицы).

ответ

21

Попробуйте сделать это с использованием чистого SQL. Это будет делать то, что вы хотите:

CREATE TABLE new_tbl LIKE orig_tbl; 
+0

Хороший звонок. «Используйте LIKE для создания пустой таблицы на основе определения другой таблицы, включая любые атрибуты столбца и индексы, определенные в исходной таблице» http://dev.mysql.com/doc/refman/5.1/en/create-table. html –

+0

Работает с MySQL (и, возможно, с большинством баз данных), но если вы используете Sqlite, это не сработает. Я столкнулся с этой проблемой в среде разработки. Производство прекрасное (это MySQL). – MiniQuark

+1

Удивительная благодарность. Обратите внимание, что ваша скопированная таблица получит индексы, но не внешние ключи. Вам придется воссоздать их отдельно. –

0

Похоже, что эта логика завершена в ActiveRecord::SchemaDumper, но она предоставляет только метод «дампа» «все-в-одном», и вы не можете сбросить только определенную таблицу (the "table" method является закрытой).

4

Это будет сделано. Это не идеально, потому что он не будет копировать параметры таблицы или индексы. Если у вас есть какие-либо параметры таблицы, вам придется добавить их к этой миграции вручную.

Чтобы скопировать индексы, вам нужно будет сформулировать запрос SQL для их выбора, а затем обработать их в новых директивах add_index. Это немного больше, чем я знаю. Но это работает для копирования структуры.

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

> он не будет копировать параметры таблицы или индексы Спасибо, но указатели - это требование. –

4

В Rails PostgreSQL, создать новую миграцию и вставить:

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

Это создаст клон с точной структурой исходной таблицы и заполнить новая таблица со старыми значениями.

Подробнее: http://www.postgresql.org/docs/9.0/static/sql-createtableas.html

+1

Осторожно с этим, так как он также скопирует столбец идентификаторов, и он не будет устанавливать его как первичный в новой таблице. –

+0

И это не будет воссоздавать индексы. –

0

Скопируйте запись таблицы из ваших проектов db/schema.rb прямо в миграции. Просто измените имя таблицы и ваше добро.

Смежные вопросы