如何解释这个Rails/PostgreSQL错误?

3
我在使用PostgreSQL和Rails时遇到了以下错误:
ActiveRecord::StatementInvalid:
       PG::NotNullViolation: ERROR:  null value in column "created_at" violates not-null constraint
       DETAIL:  Failing row contains (4, null, null, 2014-05-08 13:27:56.002747, f, null, null, f, f).
       : INSERT INTO "elements" ("updated_at") VALUES ('2014-05-08 13:27:56.002747') RETURNING "id"

我猜它的意思是我正在尝试将2014-05-08 13:27:56.002747的值插入到代表一个Element实例的行的updated_at列中。这样做应该没问题,因为这个值看起来对我来说是一个有效的日期/时间——正确吗?
我还了解到它在说created_at不能为null,但这似乎很荒谬,因为每个实例不是都会自动获得一个等于创建时间的created_at值吗?
RETURNING "id"是什么意思呢?
我很高兴继续自己调试我的应用程序,但如果有人能为我解析这个错误消息,那就是一个很好的开端。(特别是由于堆栈跟踪并没有清楚地表明错误是在哪里产生的。)

created_at字段的约束为NOT NULLDEFAULT NULL(正如您在@denis评论中所写),因此INSERT操作失败,因为您试图创建一个created_at列的NULL值行。请问您能否提供生成此错误的Ruby代码? - mdesantis
抱歉,我还找不到那一行。我的堆栈跟踪中大多数行指向Rails内部,并且我有一些影响模型触发回调的回调函数。但是你为什么说它是“DEFAULT NULL”? - steven_noble
因为从你写的评论中我猜测在迁移时你没有为created_at列指定default值,所以Rails没有设置它,因此默认值在PostgreSQL列定义中被设置为NULL。现在我在考虑,类似于t.datetime 'created_at',null: false,default: 'NOW()'这样的代码可以解决这个问题。 - mdesantis
“RETURNING *” 是 PG 的一个特性,它提供了创建记录的值,Rails 使用它来确定创建记录的 ID。 - mdesantis
2个回答

1
我也遇到了同样的问题,检查后发现我有嵌套事务。如果你遇到了同样的问题,请尝试查找。
ActiveRecord::Base.transaction

并将其删除。

因为似乎在使用事务时,created_at没有被分配(可能是bug)。

希望这可以帮助到你。


0

执行以下命令时,会提示“在列"created_at"中的空值违反了非空约束条件”:

INSERT INTO "elements" ("updated_at") VALUES ('2014-05-08 13:27:56.002747')

意思是:
  • 你缺少created_at字段的某种默认值;或者
  • 你应该手动设置created_at

抱歉,但是你的回答两部分都违反了Rails的默认设置吗?我所有表格模型的标准都是t.datetime“created_at”,null:false,Rails会在我创建新实例时自动设置created_at值。 - steven_noble
可能吧。我只是在发布您的错误信息以及在Postgres级别上它的含义。我对Rails在后台做什么或不做什么毫不知情。 - Denis de Bernardy
这是Rails 4和5之间的差异,显然在SQLite和PostGres之间的行为也有所不同。例如,在Rails 4中向现有表添加时间戳,需要添加add_timestamps(无需null:false)-然后更改更新和创建列的updated_at和created_at的null值。有关更多详细信息,请参见此帖子:https://www.viget.com/articles/adding-a-not-null-column-to-an-existing-table - ericpeters0n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接