我有一个带有全名列的表(人物),但是想要将其拆分为第一个名称(如果存在,则为初始名称)列和姓氏列。
这是一个PostgreSQL数据库FWIW。我正在创建列,所以如果可能的话,它可以在迁移中完成。这些名字都符合旧的标准美国风格,即没有复合名称或连字符。首字母后面没有句点,一些名字只是首字母。这将是一次性更改,然后任何新条目将在其单独的字段中显示名字和姓氏。全名字段将被删除。
感谢您的帮助
答案 0 :(得分:2)
您可以在单次迁移中执行此操作
创建两个新列
add_column :people, :first_name, :string
add_column :people, :last_name, :string
然后
full_names = People.all.map(&:full_name)
它返回full_name
['full_name','full_name1',...等新数组]
然后
full_names.each do |n| People.create(first_name:n.split('_')[0],
last_name:n.split('_')[1])
end
并删除full_name列
remove_column :people, :full_name
笨拙的解决方案,但应该有效
答案 1 :(得分:0)
确保不要将表架构(数据所在的列)与实际数据(具有这些列的行)混淆。
现在为什么删除last_name 列不会删除任何行是否有意义。它将保留所有行,但从所有行中删除该列。
所以,正如@xxx所说,添加列(迁移模式),然后填充它们(迁移数据)。
如果要清理从拙劣迁移中创建的所有额外记录,那么请务必备份数据库,然后再运行迁移。 ;)
但也许是一个更有帮助的答案:您可以使用created_at
日期查找作为第一次迁移的一部分创建的所有记录,然后删除它们。像
# e.g. if you want to delete all records created since
# your migration which you ran 2 days ago
People.where("created_at > ?", 2.days.ago).destroy_all
确保在尝试使用数据库之前备份数据库...
然后,回到原始问题,如何将数据从单个名称字段迁移到名/姓。添加新列后,尝试按以下方式迭代每个人:
People.each do |person|
new_first_name, new_last_name = person.name.split
person.update_attributes(
first_name: new_first_name,
last_name: new_last_name
)
end