run remove rails migrations generate data create column ruby-on-rails data-migration rails-migrations

ruby-on-rails - remove - rollback migration rails



¿Cómo muevo una columna(con contenido) a otra tabla en una migración de Rails? (7)

Esto es lo que hice en mi proyecto:

class MoveColumnDataToUsersTable < ActiveRecord::Migration[5.1] def up add_column :users, :someprop, :string User.find_each do |u| Profile.create!(user_id: u.id, someprop: someprop) end remove_column :profiles, :someprop end def down add_column :profiles, :someprop, :someprop_data_type Profile.find_each do |p| User.find_by(id: p.user_id).update_columns(someprop: p.someprop) end Profile.destroy_all end end

Necesito mover algunas columnas de una tabla existente a otra. ¿Cómo lo hago utilizando una migración de rieles?

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

Lo anterior solo crea las nuevas columnas, pero los valores se dejan vacíos ...

Quiero evitar iniciar sesión en la base de datos para actualizar manualmente las tablas.

Si hay una forma de mover los valores de columna mediante programación, ¿cuáles son las características de rendimiento? ¿Lo haría fila por fila, o hay una manera de actualizar en masa?


Haría esto como tres migraciones, o una migración de tres partes. La primera parte es agregar la columna, la segunda parte es copiar los datos y la tercera parte es soltar la columna.

Parece que el paso medio es lo que estás preguntando, puedes hacer esto en ruby ​​haciendo un bucle entre todos los usuarios y configurando la propiedad, de esta manera:

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

No amo esta forma de hacerlo, porque es muy lenta. Yo sugeriría la ejecución de sql sin formato como este:

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

Ambos asumen algo acerca de su perfil / asociación de usuarios, que puede ajustar si yo asumí mal.


La siguiente sintaxis de UPDATE funciona para las versiones recientes de Postgres y evita una subconsulta:

class MoveSomePropertyToUser < ActiveRecord::Migration def self.up add_column :users, :some_property, :string execute "UPDATE users u SET some_property = p.some_property FROM profiles p WHERE u.id = p.user_id;" remove_column :profiles, :some_property end def self.down add_column :profiles, :some_property, :string execute "UPDATE profiles p SET some_property = u.some_property FROM users u WHERE p.user_id = u.id;" remove_column :users, :some_property end end


La sintaxis no funciona para versiones posteriores de Postgres. Para obtener una respuesta actualizada de @ Eero''s for Postges 9.4.5, haga lo siguiente:

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


Para mí (postgreSQL 9.1) el RAW SQL no funcionó. Lo he cambiado:

" UPDATE users u SET someprop = (SELECT p.someprop FROM profiles p WHERE u.id = p.user_id );"



Terminé usando esta migración (probado, funciona y se deshace con éxito):

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

Me gusta porque evita las actualizaciones fila por fila en una gran base de datos.