如何使用Laravel迁移将时间戳列的默认值设置为当前时间戳?

28 浏览
0 Comments

如何使用Laravel迁移将时间戳列的默认值设置为当前时间戳?

我想使用 Laravel Schema Builder/Migrations 创建一个时间戳列,其默认值为 CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。我已经多次阅读了 Laravel 文档,但我不知道如何将其设置为时间戳列的默认值。

timestamps() 函数默认为两个时间戳列都设置为 0000-00-00 00:00

admin 更改状态以发布 2023年5月24日
0
0 Comments

为了创建created_atupdated_at两个列:

$t->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$t->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));

需要MySQL版本>=5.6.5才能拥有两个带有CURRENT_TIMESTAMP的列

0
0 Comments

给定它是一个原始表达式,你应该使用DB::raw()CURRENT_TIMESTAMP设置为列的默认值:

$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

这在每个数据库驱动程序上都可以完美运行。

从Laravel 5.1.25开始(请参见PR 10962commit 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() 快捷方式。

0