我想使用Laravel Schema Builder / Migrations创建一个时间戳列,其默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
。我已多次浏览Laravel文档,但我看不出如何将其作为timestamp列的默认值。
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()
列修饰符方法将CURRENT_TIMESTAMP
设置为列的默认值:
$table->timestamp('created_at')->useCurrent();
回到问题,在MySQL上你也可以通过ON UPDATE
使用DB::raw()
子句:
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
0000-00-00 00:00:00
不再被视为有效日期。如Laravel 5.2 upgrade guide中所述,当您将记录插入数据库时,所有时间戳列都应接收有效的默认值。您可以在迁移中使用useCurrent()
列修饰符(来自Laravel 5.1.25及更高版本)将timestamp列默认为当前时间戳,或者可以使时间戳nullable()
允许空值。CURRENT_TIMESTAMP
函数时,PostgreSQL生成具有更高精度的时间戳,从而生成带有小数秒部分的时间戳 - see this SQL fiddle。
这将导致Carbon无法解析时间戳,因为它不会期望存储微秒。为了避免这种意外行为破坏你的应用程序,你必须明确给CURRENT_TIMESTAMP
函数一个零精度,如下所示:
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP(0)'));
自Laravel 5.0以来,timestamp()
列已更改为使用默认精度为零,这避免了这一点。
感谢@andrewhl在评论中指出了这个问题。要创建created_at
和updated_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
的多个列
从2015年12月2日标记的Laravel 5.1.26开始,添加了useCurrent()
修饰符:
Schema::table('users', function ($table) {
$table->timestamp('created')->useCurrent();
});
PR 10962(其次是commit 15c487fe)领导了这一补充。
基本上,MySQL 5.7(使用默认配置)要求您为时间字段定义默认值或可为空。
这对事实不起作用:
$table->timestamp('created_at')->default('CURRENT_TIMESTAMP');
它不会删除选择时间戳时出现的“默认0”,它只会附加自定义默认值。但我们有点需要它没有引号。并非操作数据库的所有内容都来自Laravel4。这是他的观点。他希望在某些列上使用自定义默认值,例如:
$table->timestamps()->default('CURRENT_TIMESTAMP');
我认为Laravel不可能。我一直在寻找一个小时,看看是否可能。
更新:Paulos Freita的answer表明它是可能的,但语法并不简单。
请改用Paulo Freitas suggestion。
在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");
它为我创造了奇迹。
我在用户表created_at上使用这个laravel 5.X来在创建记录时自动设置时间戳。 (我们有一个客户端想直接在DB中输入用户,所以我必须确保设置时间戳)
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Carbon\Carbon;
class UpdatingUserTableTimeStampsForAccuracy extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->dateTime('created_at')->change()->default(\Carbon\Carbon::now());
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dateTime('created_at')->change();
});
}
}
如果您正在进行更改迁移,请使用该行。
如果你是Carbon的粉丝,这很棒!
或者,如果您在表创建迁移中进行设置。
$table->dateTime('created_at')->default(\Carbon\Carbon::now());
这就是你如何做到的,我已经检查了它,它适用于我的Laravel 4.2。
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
希望这可以帮助。
在Laravel 5中简单地说:
$table->timestamps(); //Adds created_at and updated_at columns.
使用以下内容:
$table->timestamp('created_at')->nullable();
希望它会对你有所帮助。谢谢。