【问题标题】:Rails 5 - Intermittent Error - ActiveRecord::NotNullViolation (Mysql2::Error: Field 'created_at' doesn't have a default valueRails 5 - 间歇性错误 - ActiveRecord::NotNullViolation(Mysql2::Error: 字段'created_at'没有默认值
【发布时间】:2020-06-09 03:27:42
【问题描述】:

需要一点帮助:)

我们有一个间歇性错误,它说我们的一个字段存在空违规:created_at

我们有几个测试环境,在我们的本地开发环境中,我们没有遇到这个问题,但是在我们的 EC2 服务器(使用 AWS Elastic Beanstalk 构建)上,我们会间歇性地遇到这个问题。 我们没有为此定义默认版本,因为我们不需要,因为 Rails 会自动使用 t.timestamps 填充此字段。我们在其他表中也有相同的 created_at 字段,没有任何问题。 我们最近从 rails 4 升级到 rails 5 和 rails 4 一切正常。

我们开始比较我们的环境设置并发现以下内容:

  • 所有环境中的 Ruby 版本 2.6.3
  • Gemfile.lock - 环境之间匹配的所有 gem
  • mysql本地是:

mysql Ver 15.1 Distrib 5.5.64-MariaDB,适用于 Linux (x86_64) 使用 阅读第 5.1 行

而EC2 mysql是:

mysql Ver 14.14 Distrib 5.5.62,适用于 Linux (x86_64),使用 readline 5.1

间歇性错误:

ActiveRecord::NotNullViolation (Mysql2::Error: Field 'created_at' 没有默认值:INSERT INTO versions (updated_at) 价值观('2020-02-25 10:55:50')) 我们正在考虑升级 mysql - 但不相信这是问题所在。 而且在 AWS Elastic Beanstalk 中升级也不容易 Schema.db

  create_table "versions", force: :cascade do |t|
    t.integer  "p_id",                        limit: 4
    t.string   "name",                              limit: 255
    t.text     "description",                       limit: 16777215
    t.datetime "created_at",                        null: false
    t.datetime "updated_at",                        null: false

迁移文件:

class CreateVersions < ActiveRecord::Migration
  def change
    create_table :versions do |t|
      t.integer :p_id
      t.string :name
      t.string :description
      t.timestamps
    end
  end
end

关于我们如何调试/修复此问题的任何想法?

【问题讨论】:

  • 嗨!你设法解决了这个问题吗?我们最近开始无缘无故地遭受同样的问题
  • 嗨,不。我们停止了此迁移工作。我们尝试从 Rails 4 迁移到 rails 5.1。所以我们目前正在使用 Rails 4。我们发现,如果您将 RACK_ENV 更改为开发环境或 Elastic 中的其他内容,它就会开始正常工作。所以只有当 RACK_ENV 是生产时才会发生这种情况。如果你发现了什么,请告诉我。
  • 我也遇到了这个错误,Rails 5.2 + MySQL
  • 我们最终设法缓解了这个问题。我们仍然不能完全确定发生了什么,但它似乎与比赛条件有关。我们有一个计划任务提交对我们的记录的更改,并且这个问题仅在执行此任务时发生。因此,我们在检索到我们想要在任务中更新的集合后添加了延迟,然后这个问题就消失了。

标签: mysql ruby-on-rails amazon-web-services


【解决方案1】:

大部分问题出在关于表列的缓存信息中。原因可能不同:

  • 您无需重新启动服务器即可即时运行迁移;
  • 您在创建新表后立即在新表中创建/更新记录。

您需要在运行迁移后使用Version.reset_column_information 重置缓存(在最坏的情况下,在create_table 之后将其直接放入迁移中)。这里是a link to the method documentation

或者您可以在运行迁移后重新启动服务器。所有缓存的列信息都将失效。

更新

我尝试的另一个选项是在迁移类中指定 Rails 兼容版本(我在这里设置了 4.2,因为您将 Rails 从 4 升级到 5):

class CreateVersions < ActiveRecord::Migration[4.2]
end

原因是 Rails 5.0 中默认的 timestamps 行为发生了变化,当使用不同的 Rails 版本运行迁移时,您会得到不同的结果。有关详细信息,请参阅this pull request。这是他们添加的弃用消息:

调用timestamp 时未指定null 的选项。在 Rails 中 5.0,此行为将更改为null: false。你应该手动 指定 null: true 以防止现有迁移的行为 从改变。

添加 [4.2] 后,它应该运行兼容 Rails 4 的迁移,并将 null: true 添加到您的时间戳字段。

您还可以将null: true 选项手动添加到迁移中。但无论如何,强烈建议在升级 Rails 版本之前将[4.2] 添加到所有迁移中。

【讨论】:

  • 我相信这不是问题,服务器已重新启动,表不是新的
  • 嘿@SergeiIakovlev,我已经更新了我的帖子,提供了更多可能解决您问题的选项。请看一看。
  • 谢谢,我会努力的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多