如何使用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_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
包含多个列
从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'));
希望这可以帮助。