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

2022-08-30 06:14:20

我想制作一个时间戳列,其默认值为使用Laravel架构生成器/迁移。我已经多次浏览了Laravel文档,我不明白如何将其设置为时间戳列的默认值。CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

该函数为其创建的两个列创建默认值。timestamps()0000-00-00 00:00


答案 1

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

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

这在每个数据库驱动程序上都能完美无缺地工作。

从 Laravel 5.1.25 开始(请参阅 PR 10962提交 15c487fe),您现在可以使用新的列修饰符方法为列实现相同的默认值:useCurrent()

$table->timestamp('created_at')->useCurrent();

回到问题,在MySQL上,你也可以通过以下方式使用子句:ON UPDATEDB::raw()

$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 开始,不再被视为有效日期。如 Laravel 5.2 升级指南中所述,当您将记录插入数据库时,所有时间戳列都应收到有效的默认值。您可以在迁移中使用列修饰符(来自 Laravel 5.1.25 及更高版本)将时间戳列默认为当前时间戳,也可以制作时间戳以允许空值。0000-00-00 00:00:00useCurrent()nullable()

  • PostgreSQL & Laravel 4.x

    在 Laravel 4.x 版本中,PostgreSQL 驱动程序使用默认数据库精度来存储时间戳值。当在具有默认精度的列上使用该函数时,PostgreSQL会生成具有更高精度的时间戳,从而生成具有小数秒部分的时间戳 - 请参阅此SQL小提琴CURRENT_TIMESTAMP

    这将导致Carbon无法解析时间戳,因为它不会期望存储微秒。为了避免这种意外行为破坏应用程序,您必须显式地为函数指定零精度,如下所示:CURRENT_TIMESTAMP

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

    自 Laravel 5.0 以来,列已更改为使用默认精度零,从而避免了这种情况。timestamp()

感谢@andrewhl在评论中指出Laravel 4.x问题。

感谢@ChanakaKarunarathne在评论中带出了新的用途CurrentOnUpdate()快捷方式。


答案 2

要同时创建 和 列: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


推荐