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

Мне нужно переместить некоторые столбцы из одной существующей таблицы в другую. Как мне это сделать с помощью миграции рельсов?

class AddPropertyToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :someprop, :string
    remove_column :profiles, :someprop
  end

  def self.down
    add_column :profiles, :someprop, :string
    remove_column :users, :someprop
  end
end

Вышеупомянутое просто создает новые столбцы, но значения остаются пустыми ...

Я хочу избежать входа в базу данных для ручного обновления таблиц.

Если есть способ программного перемещения значений столбцов, каковы характеристики производительности? Будет ли он выполнять построчное обновление или есть способ массового обновления?

28
задан Eero 26 May 2011 в 08:18
поделиться

2 ответа

Я бы сделал это как три миграции или три части миграции. Первая часть добавляет столбец, вторая часть копирует данные, а третья - отбрасывает столбец.

Похоже, средний шаг - это то, о чем вы спрашиваете, вы можете сделать это в ruby, перебрав всех пользователей и установив свойство следующим образом:

Users.each do |user|
   user.someprop = user.profile.some_prop
   user.save
end 

Я не люблю это способ сделать это, потому что это серьезно медленно. Я бы предложил выполнить raw sql следующим образом:

execute "UPDATE users u, profiles p SET u.someprop=p.someprop WHERE u.id=p.user_id"

Они оба предполагают что-то в отношении вашего профиля / ассоциации пользователей, которую вы можете настроить, если я ошибся.

6
ответ дан 28 November 2019 в 03:14
поделиться

Синтаксис не работает для более поздних версий Postgres. Чтобы получить обновленный ответ @ Eero's для Postges 9.4.5, сделайте следующее:

class AddPropertyToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :someprop, :string
    execute "UPDATE users u SET someprop = (SELECT p.someprop FROM profiles p WHERE u.id = p.user_id);"
    remove_column :profiles, :someprop
  end

  def self.down
    add_column :profiles, :someprop, :string
    execute "UPDATE profiles p SET someprop = (SELECT u.someprop FROM users u WHERE p.user_id = u.id);"
    remove_column :users, :someprop
  end
end
4
ответ дан 28 November 2019 в 03:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: