【问题标题】:Migration to change default value for a field and change all existing record's value to new default value only if it has old default value.迁移以更改字段的默认值并将所有现有记录的值更改为新的默认值,前提是它具有旧的默认值。
【发布时间】:2011-08-11 06:20:04
【问题描述】:

我需要将字段的默认值从 0 更改为 3,但问题是我已经有数千条记录,并且希望这些记录仅在记录的默认值为 0 时才将值从 0 更改为 3,但对于其他值,如 1、2,它应该保持不变。我该怎么做?

【问题讨论】:

  • 你不能只是'UPDATE table SET value = 3 WHERE value = 0'吗?

标签: mysql ruby-on-rails


【解决方案1】:

在迁移中,您应该使用 change_column 方法来更改表设置,如下所示:

change_column :my_models, :attribute_name, :integer, :default => 3

然后要更新所有现有记录,而不是遍历所有记录并单独更新它们,您可以使用 update_all 方法,如下所示:

MyModel.update_all({ :attribute_name => 3 }, { :attribute_name => 0 })

第一个参数告诉方法要设置什么值,第二个参数告诉它要更新哪些行的条件。

【讨论】:

  • 我想知道这是否仅适用于某些数据库,因为我不确定所有数据库都允许更改默认值。无论如何,我可以确认它适用于 MySQL。
  • 我刚试过这个,我认为语法可能已经改变。这对我有用:MyModel.update_all({:attribute_name => 3}, {:attribute_name => 0})
  • Rails 4 中的 update_all:Model.where("status=0").update_all(status: 2)
  • @DanneManne 谢谢 Danne 是否可以在迁移文件本身中添加它?
  • @BKSpureon 当然,这是可能的。但是,如果您这样做,有几件事值得考虑。首先是如何在迁移和回滚之间处理这个问题。简单的答案是不要将此代码放在change 块中,而是在迁移中手动定义updown,并且只在up 方法中调用update_all。第二件事是稍微长期一些,如果您最终将模型全部移除会发生什么?在这种情况下,您将得到一个使用不存在的模型的迁移。只是想一想。
【解决方案2】:
ALTER TABLE your_table MODIFY your_column tinyint(1) NOT NULL DEFAULT 3;
UPDATE your_table SET your_column=3 WHERE your_column=0;
  1. 假设您的专栏是tinyint(1),如果不一样,请替换您自己
  2. NOT NULL 假设您始终强制列为 NOT NULl

【讨论】:

    猜你喜欢
    • 2021-09-01
    • 2017-08-21
    • 2016-08-28
    • 2019-07-05
    • 2019-01-28
    • 2021-06-26
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多