【问题标题】:How can I migrate existing model (includes inserted rows) from nullable column to not nullable如何将现有模型(包括插入的行)从可为空的列迁移到不可为空的列
【发布时间】:2019-03-31 19:18:15
【问题描述】:

我用列定义创建了一个模型

create_table :admin_authentication_tokens do |t|
    t.integer :authentication_ttl
end

现在我想让authentication_ttl 不可为空。我试过这个迁移

change_column :admin_authentication_tokens, :authentication_ttl, :integer, null: false, default: 0

但出现错误 PG::NotNullViolation: ERROR: column "authentication_ttl" contains null values 我了解错误的含义,但我不想手动迁移模型。所以请给我一个用迁移文件迁移模型的方法。

【问题讨论】:

  • 我找到了答案:MyModel.where(authentication_ttl: nil).update_all(authentication_ttl: 0)

标签: ruby-on-rails ruby ruby-on-rails-5 database-migration


【解决方案1】:

您不能将NOT NULL 约束添加到包含空值的列。

无论如何,您需要在执行此类迁移之前摆脱这些值。

例如,正如您上面建议的那样,也许这些都应该设置为0

MyModel.where(authentication_ttl: nil).update_all(authentication_ttl: 0)

...或者也许这些列(其中一些)可以设置为其他值?

或者也许这些行实际上没有意义,应该删除?

MyModel.where(authentication_ttl: nil).delete_all

(或者你应该destroy_all,来触发rails回调?)

简而言之,答案实际上取决于您的具体情况。但无论如何,您需要先摆脱nulls。

请注意,如果您有生产环境和本地环境,那么在部署之前需要考虑这一点。同样,以一种或另一种方式(例如,可能通过 rake 任务),您需要在部署此类迁移之前“修复”生产数据。

【讨论】:

    猜你喜欢
    • 2013-09-10
    • 2011-08-23
    • 2011-09-29
    • 2019-02-18
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 2020-11-11
    • 2021-03-20
    相关资源
    最近更新 更多