在 Rails 迁移中从 full_name 创建 first_name 和 last_name
Create first_name and last_name from full_name in a Rails migration
我有一个带有全名列的 table(人物),但我想将其拆分为名字(如果存在则为首字母)列和姓氏列。
这是一个 PostgreSQL 数据库 FWIW。我正在创建列,所以如果可能的话,这一切都可以在迁移中完成。这些名称都符合旧标准的美国风格,即没有复合名称或连字符。首字母后没有句点,一些名字只是首字母。这将是一次更改,然后任何新条目都将在各自的字段中显示名字和姓氏。全名字段将被删除。
感谢您的帮助
您可以在单次迁移中这样做
创建两个新列
add_column :people, :first_name, :string
add_column :people, :last_name, :string
然后
full_names = People.all.map(&:full_name)
它 return full_name
['full_name','full_name1',..etc]
的新数组
然后
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
笨拙的解决方案,但应该可行
确保您没有将 table 架构(您的数据具有哪些列)与实际数据(具有这些列的行)混为一谈。
现在明白为什么删除 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
确保在尝试之前备份您的数据库...
然后,回到您最初的问题,如何将数据从单个名称字段迁移到 first/last 个名称。添加新列后,尝试像这样遍历每个人:
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
我有一个带有全名列的 table(人物),但我想将其拆分为名字(如果存在则为首字母)列和姓氏列。
这是一个 PostgreSQL 数据库 FWIW。我正在创建列,所以如果可能的话,这一切都可以在迁移中完成。这些名称都符合旧标准的美国风格,即没有复合名称或连字符。首字母后没有句点,一些名字只是首字母。这将是一次更改,然后任何新条目都将在各自的字段中显示名字和姓氏。全名字段将被删除。
感谢您的帮助
您可以在单次迁移中这样做
创建两个新列
add_column :people, :first_name, :string
add_column :people, :last_name, :string
然后
full_names = People.all.map(&:full_name)
它 return full_name
['full_name','full_name1',..etc]
然后
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
笨拙的解决方案,但应该可行
确保您没有将 table 架构(您的数据具有哪些列)与实际数据(具有这些列的行)混为一谈。
现在明白为什么删除 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
确保在尝试之前备份您的数据库...
然后,回到您最初的问题,如何将数据从单个名称字段迁移到 first/last 个名称。添加新列后,尝试像这样遍历每个人:
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