我们有script/generate migration add_fieldname_to_tablename fieldname:datatype语法,用于向模型添加新列。
在同一行中,是否有用于更改列的数据类型的脚本/generate ?或者我应该直接将SQL写入我的常规迁移中?
我想将一列从datetime改为date。
我们有script/generate migration add_fieldname_to_tablename fieldname:datatype语法,用于向模型添加新列。
在同一行中,是否有用于更改列的数据类型的脚本/generate ?或者我应该直接将SQL写入我的常规迁移中?
我想将一列从datetime改为date。
当前回答
如果在一个表中有多个列要更改,也可以使用块。
例子:
change_table :table_name do |t|
t.change :column_name, :column_type, {options}
end
有关更多细节,请参阅关于Table类的API文档。
其他回答
使用# change_column。
change_column(:table_name, :column_name, :date)
# a few more examples:
change_column(:suppliers, :name, :string, limit: 80)
change_column(:accounts, :description, :text)
注意:即使在数据库迁移之外也可以得到相同的结果,这可能对测试/调试很方便,但这个方法需要非常谨慎地使用:
ActiveRecord::Base.connection.change_column(:table_name, :column_name, :date)
如果在一个表中有多个列要更改,也可以使用块。
例子:
change_table :table_name do |t|
t.change :column_name, :column_type, {options}
end
有关更多细节,请参阅关于Table类的API文档。
这都假设列的数据类型对任何现有数据都有隐式转换。我遇到过几种情况,现有的数据,比如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
我不知道您是否可以从命令行创建一个迁移来完成所有这些,但是您可以创建一个新的迁移,然后编辑迁移以执行这个taks。
如果tablename是表的名称,fieldname是字段的名称,并且您希望从一个datetime更改到另一个日期,您可以编写一个迁移来实现这一点。
你可以创建一个新的迁移:
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
只需生成迁移:
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