script/generate migration add_fieldname_to_tablename fieldname:datatype
语法将新列添加到模型中。在同一行上,是否有用于更改列数据类型的脚本/生成器?还是应该将SQL直接写入原始迁移中?
我想将列从
datetime
更改为date
。#1 楼
我认为这应该可行。change_column :table_name, :column_name, :date
#2 楼
如果表中有多个要更改的列,也可以使用块。示例:
change_table :table_name do |t|
t.change :column_name, :column_type, {options}
end
请参阅表类以获取更多详细信息。
#3 楼
我不知道是否可以从命令行创建迁移来完成所有这些操作,但是可以创建新的迁移,然后编辑该迁移以执行此任务。如果tablename是名称表的字段名是您的字段名,并且您想要从日期时间更改为日期,可以编写一个迁移来做到这一点。
您可以使用以下方法创建新的迁移:
rails g migration change_data_type_for_fieldname
然后编辑迁移以使用change_table:
class ChangeDataTypeForFieldname < ActiveRecord::Migration
def self.up
change_table :tablename do |t|
t.change :fieldname, :date
end
end
def self.down
change_table :tablename do |t|
t.change :fieldname, :datetime
end
end
end
然后运行迁移:
rake db:migrate
#4 楼
正如我在前面的答案中发现的那样,更改列的类型需要三个步骤:步骤1:
使用以下代码生成新的迁移文件:
rails g migration sample_name_change_column_type
步骤2:
转到
/db/migrate
文件夹并编辑您制作的迁移文件。有两种不同的解决方案。def change
change_column(:table_name, :column_name, :new_type)
end
def up
change_column :table_name, :column_name, :new_type
end
def down
change_column :table_name, :column_name, :old_type
end
步骤3:
不要忘记执行以下命令:
rake db:migrate
我已经为Rails 4测试了该解决方案,并且效果很好。
评论
在步骤2中,第一个将在运行rake db:rollback后失败,建议您检查第二个
– Feuda
16 Dec 14'9:45
是否有Rails约定,允许在生成迁移文件时不做任何修改然后再编辑它,或多或少地完成所有工作?
– BKSpurgeon
17年1月19日在23:52
@BKSpurgeon是的,请在此处查看文档:edgeguides.rubyonrails.org/active_record_migrations.html
–阿布扎尔·拉贾比(Aboozar Rajabi)
17年1月20日在9:13
#5 楼
使用Rails 5来自Rails指南:
如果您希望迁移执行Active Record不知道如何撤消的操作,则可以使用
reversible
:class ChangeTablenameFieldname < ActiveRecord::Migration[5.1]
def change
reversible do |dir|
change_table :tablename do |t|
dir.up { t.change :fieldname, :date }
dir.down { t.change :fieldname, :datetime }
end
end
end
end
#6 楼
只需生成迁移:rails g migration change_column_to_new_from_table_name
像这样更新迁移:
class ClassName < ActiveRecord::Migration
change_table :table_name do |table|
table.change :column_name, :data_type
end
end
,最后
rake db:migrate
#7 楼
所有这些都假定该列的数据类型具有对任何现有数据的隐式转换。我遇到了几种情况,其中现有数据(例如String
)可以隐式转换为新数据类型(例如Date
)。 在这种情况下,了解您可以使用数据转换创建迁移会很有帮助。就个人而言,我喜欢将它们放入模型文件中,然后在所有数据库模式都已迁移且稳定之后将其删除。
/app/models/table.rb
...
def string_to_date
update(new_date_field: date_field.to_date)
end
def date_to_string
update(old_date_field: date_field.to_s)
end
...
def up
# Add column to store converted data
add_column :table_name, :new_date_field, :date
# Update the all resources
Table.all.each(&:string_to_date)
# Remove old column
remove_column :table_name, :date_field
# Rename new column
rename_column :table_name, :new_date_field, :date_field
end
# Reversed steps does allow for migration rollback
def down
add_column :table_name, :old_date_field, :string
Table.all.each(&:date_to_string)
remove_column :table_name, :date_field
rename_column :table_name, :old_date_field, :date_field
end
#8 楼
使用迁移更改数据类型的另一种方法步骤1:
您需要使用迁移来删除故障的数据类型字段名称
例如:
rails g migration RemoveFieldNameFromTableName field_name:data_type
这里不要忘记为字段指定数据类型
步骤2:
现在,您可以添加具有正确数据类型的字段
例如:
rails g migration AddFieldNameToTableName field_name:data_type
就这样,现在您的表将添加正确的数据类型字段,使用快乐的ruby编码!!
评论
值得一提的是,此方法将丢失该列中的所有数据。
–山姆·菲格罗亚(Sam Figueroa)
20-10-28在7:28
是的,当然,如果该列中有数据,请先添加该列,然后再从现有列中提取数据
– Prasanth_Rubyist
20-10-28在7:34
并非每个人都处于相同的编码级别。因此,对于所有人,尤其是初学者来说,这并不明显。由于这个SO问题是关于更改列类型而不是重新创建它的,所以我认为这是一个有效的警告。
–山姆·菲格罗亚(Sam Figueroa)
20-11-19在7:02
#9 楼
要在编辑默认值的情况下完成答案,请执行以下操作:在Rails控制台中:
rails g migration MigrationName
在迁移中:
def change
change_column :tables, :field_name, :field_type, default: value
end
外观如下:
def change
change_column :members, :approved, :boolean, default: true
end
评论
@b_ayan:据我所知,迁移名称中唯一神奇的词是“添加”和“删除”。
– Alex Korban
2010年5月10日22:57
排序滑轨新手,但是…我理解答案,但对这个答案的评论不了解。感谢澄清:)
–艾伦·H。
2011-10-12 1:25
创建迁移时,请为其命名(例如,上面问题中的add_fieldname_to_tablename)。如果它以“ add”或“ remove”开头,则迁移将自动使用代码来填充以添加或删除列,从而省去了您自己编写代码的麻烦。
– Alex Korban
2011年10月26日19:35
还要记住,您应该用单独的上,下操作来替换常规的更改操作,因为change_column是不可逆的迁移,如果需要回滚,则会引发错误。
– DaveStephens
2015年4月6日17:09
@QPaysTaxes上应包含要在列之间更改的内容,而下应包含如何撤消更改的内容。
– DaveStephens
16年1月24日在14:02