如何将现有模型(包括插入的行)从可空列迁移到不可为空

gia*_*pnh 2 ruby ruby-on-rails database-migration ruby-on-rails-5

我创建了一个带有列定义的模型

create_table :admin_authentication_tokens do |t|
    t.integer :authentication_ttl
end
Run Code Online (Sandbox Code Playgroud)

现在我想让它authentication_ttl不可空.我试过这个迁移

change_column :admin_authentication_tokens, :authentication_ttl, :integer, null: false, default: 0
Run Code Online (Sandbox Code Playgroud)

但得到一个错误, PG::NotNullViolation: ERROR: column "authentication_ttl" contains null values 我明白错误意味着什么,但我不想手动迁移模型.那么请给我一种方法来迁移模型与迁移文件.

Tom*_*ord 5

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

无论如何,您需要在执行此类迁移之前删除这些值.

例如,如上所述,也许这些都应设置为0:

MyModel.where(authentication_ttl: nil).update_all(authentication_ttl: 0)
Run Code Online (Sandbox Code Playgroud)

...或者可能还有一些其他值(某些)这些列可以设置为?

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

MyModel.where(authentication_ttl: nil).delete_all
Run Code Online (Sandbox Code Playgroud)

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

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

请注意,如果您有生产环境以及本地生产环境,则在部署之前需要考虑这一点.再次,无论如何(例如,可能通过rake任务),您需要在部署此类迁移之前"修复"生产数据.