向现有表添加非空列的问题

10

我在向表中添加非空列时遇到了问题。我阅读了很多关于这个问题的帖子,它应该是正确的。

迁移代码:

  def change
    add_column :individual_trainings, :start_on, :time
    add_column :individual_trainings, :end_on, :time

    change_column_null :individual_trainings, :start_on, false
    change_column_null :individual_trainings, :end_on, false
  end

错误:

PG::NotNullViolation: ERROR:  column "start_on" contains null values...

我不知道为什么它不起作用。我应该如何正确编写更改方法?

提前致谢。

更新: 这是我的大错。在这个表中,我有一条记录...我清空了表并进行了迁移。现在它可以工作了。对于我的愚蠢和浪费你们的时间,我很抱歉。


我不确定你的具体情况,但你可以使用这个 add_column :individual_trainings, :start_on, :time, default: false,然后尝试看看是否有效。 - ciaoben
最近我写了一个迁移脚本,做的正是你现在要做的事情。但是在我的情况下,我删除了所有带有空值的记录。因为从现在开始,我们的数据库不应该再接受空值。你能否删除这些带有空值的记录呢? - Adriano Tadao
@AdrianoTadao,我在这张表中没有任何记录。 - Prezes Łukasz
你尝试过像这样的操作吗?change_column :individual_trainings, :start_on, :datetime, null: false如果你没有任何记录,那么就非常奇怪了。你确定吗?你可以通过 postico 或 psql 检查一下。也许你有一些隐藏的记录,我不确定。xD - Adriano Tadao
3个回答

18

如果你的individual_trainings表中没有任何记录,你的迁移将会成功。

由于你的表中有记录,当你添加start_on列时,立即将列值设置为null,然后对其施加NOT NULL约束。这就是为什么你会得到这个错误。

解决方案:

在添加start_onend_on列时,只需设置一个默认值(除了null),然后继续进行迁移以强制实施NOT NULL约束。


5
我认为问题出在你在这里说:start_on 不能为null (这里有解释):

change_column_null :individual_trainings, :start_on, false

但是你却把它留空了null

在创建列时添加一个默认值就可以解决问题:

add_column :individual_trainings, :start_on, :time, default: false

3

试试这个:

 def change
   change_column_default :individual_trainings, :start_on, Time.now
   change_column_default :individual_trainings, :end_on, Time.now
 end

若要了解更多细节,请参阅http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_column_default

设置非空约束,请按照以下步骤进行:

def change
  change_column :individual_trainings, :start_on, :time, :null => false
  change_column :individual_trainings, :end_on, :time, :null => false
end

如果我尝试您的建议,我会遇到这个错误:ActiveRecord :: StatementInvalid:PG :: InvalidDatetimeFormat:ERROR:类型为time的无效输入语法:“f” :ALTER TABLE“individual_trainings” ALTER COLUMN“start_on” SET DEFAULT'f' - Prezes Łukasz
这是因为你使用了 time 类型,所以你必须将 当前日期 设置为默认值。请查看更新后的代码。 - Amol Udage
不完全正确,因为我想要为列设置非空,而不是默认值。 - Prezes Łukasz
是的,默认值是另一回事。你的错误非常奇怪。@ŁukaszKorol,请告诉我们您是如何解决这个问题的。 - Adriano Tadao
这是我的大错。我在这个表中有一条记录...我清空了表并进行了迁移。现在它可以工作了。 - Prezes Łukasz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接