Обновить один столбец в значение другого в рельсы миграции


у меня есть таблица в приложения Rails с сотнями тысяч записей, и у них есть только created_at метки. Я добавлю возможность редактировать эти записи, поэтому я хочу добавить updated_at типа timestamp в таблице. В моей миграции, чтобы добавить столбец, я хочу обновить все строки, чтобы иметь новый updated_at матч старых created_at, так как это значение по умолчанию для вновь созданных строк в Rails. Я мог бы сделать find(:all) и перебирать записи, но это займет несколько часов из-за размера стол. Что я действительно хочу сделать, это:

UPDATE table_name SET updated_at = created_at;

есть ли лучший способ сделать это в миграции Rails с помощью ActiveRecord, а не выполнять необработанный SQL?

4 60

4 ответа:

Я бы создал миграции

rails g migration set_updated_at_values

и внутри него напишите что-то вроде:

class SetUpdatedAt < ActiveRecord::Migration
  def self.up
    Yourmodel.update_all("updated_at=created_at")
  end

  def self.down
  end
end

таким образом вы добьетесь двух вещей

  • это повторяемый процесс, с каждым возможным развертыванием (где это необходимо) он выполняется
  • это эффективно. Я не могу придумать более рубиновое решение (это так же эффективно).

Примечание: Вы также можете запустить необработанный sql внутри миграции, если запрос становится слишком сложным для записи с помощью и ActiveRecord. Просто напишите следующее:

Yourmodel.connection.execute("update your_models set ... <complicated query> ...")

можно использовать update_all, а который работает очень похоже на raw SQL. Это все варианты, которые у вас есть.

кстати лично я не обращаю столько внимания на миграции. Иногда raw SQL-это действительно лучшее решение. Обычно код миграции не используется повторно. Это одноразовое действие, поэтому я не беспокоюсь о чистоте кода.

как писал грегдан, вы можете использовать update_all. Вы можете сделать что-то вроде этого:

Model.where(...).update_all('updated_at = created_at')

первая часть-это ваш типичный набор условий. В последней части говорится, как выполнять задания. Это даст UPDATE заявление, по крайней мере, в Rails 4.

как однократная операция, я бы просто сделал это в rails console. Это действительно займет несколько часов? Может быть, если есть миллионы записей...

records = ModelName.all; records do |r|; r.update_attributes(:updated_at => r.created_at); r.save!; end;`