在 ROR 迁移期间将列类型从 Date 更改为 DateTime
Posted
技术标签:
【中文标题】在 ROR 迁移期间将列类型从 Date 更改为 DateTime【英文标题】:Change a column type from Date to DateTime during ROR migration 【发布时间】:2011-07-08 15:56:13 【问题描述】:我需要将我正在制作的应用的列类型从日期更改为日期时间。我不关心数据,因为它仍在开发中。
我该怎么做?
【问题讨论】:
【参考方案1】:首先在您的终端中:
rails g migration change_date_format_in_my_table
然后在你的迁移文件中:
对于 Rails >= 3.2:
class ChangeDateFormatInMyTable < ActiveRecord::Migration
def up
change_column :my_table, :my_column, :datetime
end
def down
change_column :my_table, :my_column, :date
end
end
【讨论】:
你说得对,我只是假设初学者会选择可用的最新技术,但这当然是不确定的 问题标记为“ruby-on-rails-3” @Sucrenoir 是的,标签是在他回答后通过 apneadiving 添加的。 如果您想知道为什么不使用单个change
方法来代替 up
和 down
方法,那是因为 the change
method doesn't support the change_column
migration definition。
这个答案只是部分正确,即使在 rails 4 上也不能在 change 中使用 change_column ,否则向下迁移将不起作用。无论 rails 的版本如何,您都应该使用 up/down。【参考方案2】:
此外,如果您使用的是 Rails 3 或更新版本,则不必使用 up
和 down
方法。你可以使用change
:
class ChangeFormatInMyTable < ActiveRecord::Migration
def change
change_column :my_table, :my_column, :my_new_type
end
end
【讨论】:
更改方法仅适用于可逆迁移。上面的代码会抛出 ActiveRecord::IrreversibleMigration 异常。在 change 方法中只能使用 api.rubyonrails.org/classes/ActiveRecord/Migration/… 中的方法。 我正在运行 Rails 4,之前做过这种迁移。改变不起作用! @davekaro 的评论是正确的。 对于 Rails 5,这是正确且有效的解决方案。 当被反转时,它如何知道它应该改回的旧列类型是什么? @AndrewGrimm 你是对的。这是我在尝试逆转迁移时看到的:This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.
【参考方案3】:
在 Rails 3.2 和 Rails 4 中,Benjamin 的 popular answer 语法略有不同。
首先在您的终端中:
$ rails g migration change_date_format_in_my_table
然后在你的迁移文件中:
class ChangeDateFormatInMyTable < ActiveRecord::Migration
def up
change_column :my_table, :my_column, :datetime
end
def down
change_column :my_table, :my_column, :date
end
end
【讨论】:
【参考方案4】:有一个change_column 方法,只需在迁移中执行它,将 datetime 作为新类型即可。
change_column(:my_table, :my_column, :my_new_type)
【讨论】:
这会保留原始数据吗? 是的,保留原始数据【参考方案5】:AFAIK,迁移是为了在进行架构更改时尝试重塑您关心的数据(即生产)。因此,除非那是错误的,并且既然他确实说过他不关心数据,为什么不直接从日期到日期时间修改原始迁移中的列类型并重新运行迁移呢? (希望你有测试:))。
【讨论】:
你可能会关心在开发环境中使用迁移,即使你不关心数据,如果你在一个团队中工作并且你希望你的架构更改传播到所有其他人您团队中的开发人员。 在这种情况下,我无法看到额外迁移来更改列会给您带来什么好处。更改创建列的原始迁移有什么问题?无论哪种情况,每个团队成员都必须重新运行所有迁移以获取新架构。 如果您使用新的迁移,您可以撤消更改列类型的迁移。如果您要编辑原始文件,则必须回滚该编辑并在此之后重新运行迁移。 考虑到还没有生产数据,这实际上是一个非常谨慎的答案。对于那些担心其他团队成员的人,这就是rake db:migrate:reset
的用途。以上是关于在 ROR 迁移期间将列类型从 Date 更改为 DateTime的主要内容,如果未能解决你的问题,请参考以下文章
Postgres 和 Laravel 如何将列从字符串类型更改为整数?
Sequelize PostgreSQL:将列类型字符串更改为字符串数组
Oracle SQL 在包含数据时将列类型从数字更改为 varchar2