Как можно клонировать таблицу базы данных с помощью миграции Rails?

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

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

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

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

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


person Teflon Ted    schedule 09.10.2009    source источник


Ответы (5)


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

CREATE TABLE new_tbl LIKE orig_tbl;
person zenazn    schedule 12.10.2009
comment
Хороший звонок. Используйте LIKE для создания пустой таблицы на основе определения другой таблицы, включая любые атрибуты столбцов и индексы, определенные в исходной таблице dev.mysql.com/doc/refman/5.1/en/create-table.html - person Teflon Ted; 12.10.2009
comment
Работает с MySQL (и, возможно, с большинством баз данных), но если вы используете Sqlite, это не сработает. Я столкнулся с этой проблемой в среде разработки. Производство в порядке (это MySQL). - person MiniQuark; 17.09.2010
comment
Огромное спасибо. Обратите внимание, что ваша скопированная таблица получит индексы, но не внешние ключи. Вам придется воссоздать их отдельно. - person Rich Sutton; 10.10.2012
comment
Для тех, кто пользуется PostgreSQL: CREATE TABLE new_tbl (LIKE orig_tbl INCLUDING DEFAULTS INCLUDING INDEXES); или INCLUDING ALL для клонирования всего - person Fletcher91; 20.09.2014
comment
Вот полезный ответ в другом сообщении для двух команд для клонирования и копирования всех данных в другую таблицу: stackoverflow.com/a/3280042/513739 - person Excalibur; 03.06.2015
comment
не могли бы вы объяснить, как это использовать при миграции? - person wuliwong; 07.11.2018
comment
Будет ли это правильно синхронизироваться с schema.rb? ИЗМЕНИТЬ - Отвечая на мой вопрос: да - stackoverflow.com/questions/3815447/ - person David Bodow; 23.07.2019

В Rails 4 и 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

person htaidirt    schedule 10.05.2014
comment
Будьте осторожны с этим, так как он также скопирует столбец идентификатора и не сделает его основным в новой таблице. - person Guillermo Siliceo Trueba; 14.04.2015
comment
И он не будет воссоздавать индексы. - person Thomas Andrews; 22.03.2018

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

Чтобы скопировать индексы, вам нужно будет сформулировать 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
person EmFi    schedule 12.10.2009
comment
›Он не будет копировать параметры таблицы или индексы. Спасибо, но индексы - это требование. - person Teflon Ted; 12.10.2009
comment
Лол, я хотел что-то, что клонирует без индекса - person Subham Padhi; 25.12.2020

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

person Teflon Ted    schedule 11.10.2009

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

person Weston Ganger    schedule 05.05.2016