我用列定义创建了一个模型
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
我了解错误的含义,但我不想手动迁移模型。因此,请给我一种使用迁移文件迁移模型的方法。
答案 0 :(得分:5)
您不能向包含空值的列添加NOT NULL
约束。
一种或另一种方法,在执行这种迁移之前,您需要摆脱这些值。
例如,如上所述,也许这些都应设置为0
:
MyModel.where(authentication_ttl: nil).update_all(authentication_ttl: 0)
...或者也许还有一些其他值可以设置为(某些)列?
也许这些行实际上没有意义,应该删除吗?
MyModel.where(authentication_ttl: nil).delete_all
(或者也许应该destroy_all
来触发rails回调?)
简而言之,答案确实取决于您的具体情况。但是,无论哪种方式,您都需要先摆脱null
。
请注意,如果您既有生产环境又有本地环境,则在部署之前需要将其考虑在内。同样,通过一种或多种方式(例如,通过rake任务),您需要在部署此类迁移之前先“修复”生产数据。