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

我想使用Laravel Schema Builder / Migrations创build一个默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP的时间戳列。 我已经多次浏览了Laravel文档,而且我也没有看到如何将时间戳列设置为默认值。

timestamps()函数为它所创build的两列创build默认值0000-00-00 00:00

由于这是一个原始expression式,因此应该使用DB::raw()CURRENT_TIMESTAMP设置为列的默认值:

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

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

从Laravel 5.1.25开始(请参阅PR 10962和提交15c487fe ),可以使用新的useCurrent()列修饰符方法将CURRENT_TIMESTAMP设置为列的默认值:

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

正如在MySQL上所问,你也可以通过DB::raw()使用ON UPDATE子句:

 $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')); 

陷阱

  • MySQL的

    从MySQL 5.7开始, 0000-00-00 00:00:00不再被认为是有效的date。 如Laravel 5.2升级指南中所述 ,将logging插入数据库时​​,所有时间戳记列都应该接收有效的缺省值。 您可以在迁移中使用useCurrent()列修饰符(来自Laravel 5.1.25及更高版本)以将时间戳列默认设置为当前时间戳,或者可以使时间戳nullable()允许空值。

  • PostgreSQL&Laravel 4.x

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

    这将导致碳分析时间戳失败,因为它不会预期存储微秒。 为了避免这种意外的行为破坏你的应用程序,你必须明确地给CURRENT_TIMESTAMP函数一个零精度,如下所示:

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

    由于Laravel 5.0, timestamp()列已更改为使用默认精度为零,从而避免了这一点。

    感谢@andrewhl在评论中指出了这个问题。

要创buildcreated_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包含多个列

从Laravel 5.1.26开始,在2015-12-02上标记,添加了useCurrent()修饰符:

 Schema::table('users', function ($table) { $table->timestamp('created')->useCurrent(); }); 

PR 10962 (其次是提交15c487fe )引发了这个增加。

您也可能想要阅读感兴趣的问题3602和11518 。

基本上,MySQL 5.7(使用默认configuration)要求您为时间字段定义默认值或可为空。

改为使用Paulo Freitas的build议 。


在Laravel修复此问题之前,可以在Schema::create运行之后运行标准数据库查询。

  Schema::create("users", function($table){ $table->increments('id'); $table->string('email', 255); $table->string('given_name', 100); $table->string('family_name', 100); $table->timestamp('joined'); $table->enum('gender', ['male', 'female', 'unisex'])->default('unisex'); $table->string('timezone', 30)->default('UTC'); $table->text('about'); }); DB::statement("ALTER TABLE ".DB::getTablePrefix()."users CHANGE joined joined TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL"); 

它为我创造了奇迹。

这不适用于一个事实:

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

它不会删除似乎与select时间戳来的“默认0”,它只是附加自定义默认值。 但是,我们有需要没有引号。 并非所有操纵数据库的东西都来自Laravel4。 这是他的观点。 他希望在某些列上自定义默认值,例如:

 $table->timestamps()->default('CURRENT_TIMESTAMP'); 

我不认为Laravel是可能的。 我一直在寻找一个小时,看是否有可能。


更新: Paulos Freita的答案显示,这是可能的,但语法不直截了当。

在Laravel 5中简单地说:

 $table->timestamps(); //Adds created_at and updated_at columns. 

文档: http : //laravel.com/docs/5.1/migrations#creating-columns

这是你怎么做的,我已经检查过它,它在我的Laravel 4.2上工作。

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

希望这可以帮助。