如何使用Laravel迁移将时间戳列的默认值设置为当前时间戳?
如何使用Laravel迁移将时间戳列的默认值设置为当前时间戳?
我想使用 Laravel Schema Builder/Migrations 创建一个时间戳列,其默认值为 CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
。我已经多次阅读了 Laravel 文档,但我不知道如何将其设置为时间戳列的默认值。
timestamps()
函数默认为两个时间戳列都设置为 0000-00-00 00:00
。
给定它是一个原始表达式,你应该使用DB::raw()
将CURRENT_TIMESTAMP
设置为列的默认值:
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
这在每个数据库驱动程序上都可以完美运行。
从Laravel 5.1.25开始(请参见PR 10962和commit 15c487fe),您现在可以使用新的useCurrent()
列修饰符方法来实现列的相同默认值:
$table->timestamp('created_at')->useCurrent();
回到问题,对于MySQL,您还可以通过DB :: raw()
使用ON UPDATE
子句:
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
同样,从Laravel 8.36.0开始(请参见PR 36817),您现在可以使用新的useCurrentOnUpdate()
列修饰符方法和useCurrent()
修饰符来实现列的相同默认值:
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();
注意事项
-
MySQL
从MySQL 5.7开始,
0000-00-00 00:00:00
不再被视为有效日期。如Laravel 5.2升级指南文档所述,当您向数据库插入记录时,所有时间戳列应该接收有效的默认值。您可以在迁移中使用useCurrent()
列修饰符(自Laravel 5.1.25及以上版本)将时间戳列默认为当前时间戳,或者您可以使时间戳nullable()
以允许空值。 -
PostgreSQL & Laravel 4.x
在 Laravel 4.x 版本中,PostgreSQL 驱动程序使用默认数据库精度存储时间戳值。当在具有默认精度的列上使用
CURRENT_TIMESTAMP
函数时,PostgreSQL 生成一个具有更高可用精度的时间戳,从而生成具有分数秒部分的时间戳 - 参见此 SQL 案例。这将导致 Carbon 无法解析时间戳,因为它不会期望微秒被存储。为了避免这种意外行为破坏应用程序,您必须显式地给
CURRENT_TIMESTAMP
函数提供零精度,如下所示:$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP(0)'));
自 Laravel 5.0 以来,
timestamp()
列已更改为使用默认精度为零,从而避免了这种情况。
感谢@andrewhl在评论中指出 Laravel 4.x 问题。
感谢@ChanakaKarunarathne在评论中介绍新的 useCurrentOnUpdate()
快捷方式。