在我的general_exams
表格中,我有一个名为semester
的列,类型为string
。现在我想将其名称更改为semester_id
,输入为integer
。我已阅读有关迁移的内容,它有可用的转换:
所以,我创建了这样的迁移文件:
class RenameSemesterFromGeneralExams < ActiveRecord::Migration
def change
rename_column :general_exams, :semester, :semester_id
change_column :general_exams, :semester_id, :integer
end
end
但是,当我运行rake db:migrate
时,它有错误:
== RenameSemesterFromGeneralExams: migrating =================================
-- rename_column(:general_exams, :semester, :semester_id)
-> 0.0572s
-- change_column(:general_exams, :semester_id, :integer)
rake aborted!
An error has occurred, this and all later migrations canceled:
PG::Error: ERROR: column "semester_id" cannot be cast to type integer
: ALTER TABLE "general_exams" ALTER COLUMN "semester_id" TYPE integer
在我的表GeneralExam中,我销毁了所有数据。 所以,任何人都可以告诉我该怎么做?或者我必须创建两个迁移文件?
答案 0 :(得分:16)
这适用于Rails 4
def change
rename_column :general_exams, :semester, :semester_id
change_column :general_exams, :semester_id, :integer
end
答案 1 :(得分:10)
您的问题可能是semester
包含无法转换为integers
的数据。这就是你得到施法错误的原因。
我怀疑你需要做更多工作来完成这项工作,因为唯一想到的就是删除列并创建一个具有正确值的新列。
但是你可以在一次迁移中简单地删除_column然后再添加add_column。这应该完美无缺。
我还建议您先添加add_column,然后执行映射过程,将旧semester
值映射到新semester_id
,然后删除列。
请记住,您可以在迁移中执行ActiveRecord操作。所以你可以把那些代码放在那里。
答案 2 :(得分:0)
此错误是因为表中存在数据(或默认值,可能是..),PG不知道如何从字符串转换为整数。要么使用PG特定的SQL(我想你需要USING
)和execute
迁移命令来摆脱数据或告诉PG你想如何转换它。请参阅有关迁移的Rails指南。
答案 3 :(得分:0)
我希望这个帮助
class ModifyColumnTables def change remove_column :posts, :old_column add_column :posts, :new_column, :type_of_column end end
答案 4 :(得分:0)
您可以通过一次迁移来做到这一点。但这并不总是有效,您可能会遇到错误,尤其是在将列从布尔类型转换为整数类型,或将字符串类型转换为整数类型时,除非您具体说明如何转换此数据。
所以您在 general_exams
表中有一个名为 semester
的列,它是一个字符串。您想将其重命名为 semester_id
并将其类型更改为整数。
在您执行上述任何操作之前,请确保您的工作已提交到 git,这样您就可以随时重置为旧提交并重新开始,而不会丢失您的工作。
在你的终端运行
rails g migration rename_the_column_semester_to_semester_id
这将为您生成迁移。现在打开您的迁移文件。
db/migrate/20210xxx_rename_the_column_semester_to_semester_id.rb
它看起来像这样:
class RenameTheColumnSemesterToSemesterID < ActiveRecord::Migration
def change
end
end
在更改方法中,使您的文件看起来像这样。
class RenameTheColumnSemesterToSemesterID < ActiveRecord::Migration
def change
rename_column :general_exams, :semester, :semester_id
change_column :general_exams, :semester_id, :integer, using: 'semester_id::integer'
end
end
或者您可以这样做:
class RenameTheColumnSemesterToSemesterID < ActiveRecord::Migration
def change
rename_column :general_exams, :semester, :semester_id
change_column :general_exams, :semester_id, 'integer USING CAST(semester_id AS integer)'
end
end
注意事项:
仅当您的列在表中没有默认值时,上述内容才有效。这很重要,因为如果您已经为您的列设置了默认值,您仍然会收到类似 PG::DatatypeMismatch: ERROR: default for column "semester_id" cannot be cast automatically to semester integer
的错误,PG 会抱怨您的学期列已经有了默认值。在这种情况下,您需要在重命名列并设置新的默认值后删除默认值。
class RenameTheColumnSemesterToSemesterID < ActiveRecord::Migration
def change
rename_column :general_exams, :semester, :semester_id
execute "ALTER TABLE general_exams ALTER semester_id DROP DEFAULT;"
change_column :general_exams, :semester_id, :integer, using: 'semester_id::integer', default: 1
end
end
当然,您可以设置任何您想要的默认值,以防您在模型中从 0、1、2 或其他任何值进行枚举。
保存您的迁移。并运行
rails db:migrate