【问题标题】:Setting postgres datetime column to nil in rails migration在 Rails 迁移中将 postgres 日期时间列设置为 nil
【发布时间】:2012-07-31 15:35:34
【问题描述】:

我正在编写一个在 postgres 表中填充 premium_from datetime 列的 Rails 迁移。

我对人口没有问题,但我一直在为迁移编写回滚方法,因为当我尝试将 datetime 属性更改回nil 时,rails 或 postgres 似乎什么都不做。我也无法得到任何有用的错误消息,所以我完全不确定发生了什么。

这是我最近的迭代(出于绝望,我尝试单独处理帐户,因为似乎也没有其他方法):

def self.down
  Account.where('premium_from is not null').each do |a| 
    a.update_attribute(:premium_from, 'null')
  end
end

这愉快地运行了大约 7 秒,然后让我所有填充的 premium_from 条目仍然完好无损,我也无法在谷歌中找到任何有用的东西。

有人知道如何在 postgres 中将日期时间列条目设置为 nil 吗?

或者我只是忽略了一些明显的东西?

编辑:向上看起来像这样

csv.each do |row|
  if account = Account.premium.find_by_name(row.first)
    # This .find is necessary because .premium uses a join, meaning that it returns
    # read-only objects
    Account.find(account.id).update_attribute(:premium_from, Time.parse(row.last))
  end
end

【问题讨论】:

  • 已添加。如果您想知道的话,premium_from 列是在之前的迁移中添加的。

标签: ruby-on-rails postgresql rails-migrations


【解决方案1】:

首先,我会避免在迁移中引用Account 类,除非您在迁移本身中定义了Account 类。这始终是明智的做法,因为您可能会重构 Account 类并在未来将其命名为不同的名称,这样迁移就不会运行。像class Account < ActiveRecord::Base; end 这样的东西应该可以。

除此之外,我建议在这种情况下只使用 SQL。它很简单,并且性能会更好。无需将所有这些记录带入并构建 AR 对象,只需发布​​更新即可。这是我的做法:

execute "UPDATE accounts SET premium_from = NULL where premium_from IS NOT NULL;"

【讨论】:

  • 轰隆隆,完美运行。我知道这会很容易!关于Account - 这在应用程序中非常重要,因此将来真的没有机会改变它。不过建议很好,以后我会记住的。
【解决方案2】:

你试过了吗:

a.update_attribute(:premium_from, nil)

您的列是否允许在 postgres 中使用空值?

【讨论】:

  • 我确实尝试过,但也没有用 - 我真的不知道那里发生了什么。 hgmnz 的 SQL 很好地完成了这项工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-23
  • 1970-01-01
相关资源
最近更新 更多