Eer*_*ero 28 data-migration ruby-on-rails rails-migrations
我需要将一些列从一个现有表移动到另一个表.如何使用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
Run Code Online (Sandbox Code Playgroud)
以上只是创建新列,但值保持为空...
我想避免登录到数据库以手动更新表.
如果有一种以编程方式移动列值的方法,那么性能特征是什么?它会逐行进行,还是有办法批量更新?
Eer*_*ero 35
我最终使用了这个迁移(测试,它可以工作,并成功回滚):
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
Run Code Online (Sandbox Code Playgroud)
我喜欢它,因为它避免了大型数据库上的逐行更新.
Oll*_*ett 11
以下UPDATE
语法适用于最近的 Postgres 版本并避免子查询:
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
Run Code Online (Sandbox Code Playgroud)
我会这样做三次迁移,或三次迁移.第一部分是添加列,第二部分是复制数据,第三部分是删除列.
这听起来像你要问的中间步骤,你可以通过循环所有用户并设置属性来在ruby中执行此操作,如下所示:
Users.each do |user|
user.someprop = user.profile.some_prop
user.save
end
Run Code Online (Sandbox Code Playgroud)
我不喜欢这种做法,因为它非常慢.我建议像这样执行原始的sql:
execute "UPDATE users u, profiles p SET u.someprop=p.someprop WHERE u.id=p.user_id"
Run Code Online (Sandbox Code Playgroud)
这些都假设您的个人资料/用户关联,如果我认为错误,您可以调整.
该语法不适用于更高版本的 Postgres。对于@Eero's for 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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13342 次 |
最近记录: |