我想使用Laravel Schema Builder / Migrations创建一个默认值为CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
的时间戳列。我已多次浏览Laravel文档,但我不知道如何将其作为时间戳列的默认值。
timestamps()
函数为其生成的两列创建默认值0000-00-00 00:00
。
答案 0 :(得分:227)
鉴于它是原始表达式,您应该使用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'));
<强>的MySQL 强>
从MySQL 5.7开始,0000-00-00 00:00:00
不再被视为有效日期。正如Laravel 5.2 upgrade guide中所述,当您将记录插入数据库时,所有时间戳列都应该收到有效的默认值。您可以在迁移中使用useCurrent()
列修饰符(来自Laravel 5.1.25及更高版本)将timestamp列默认为当前时间戳,或者可以使时间戳nullable()
允许空值。< / p>
PostgreSQL&amp; Laravel 4.x
在Laravel 4.x版本中,PostgreSQL驱动程序使用默认数据库精度来存储时间戳值。在具有默认精度的列上使用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在评论中指出了这个问题。
答案 1 :(得分:43)
要同时创建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版本&gt; = 5.6.5才能拥有多个CURRENT_TIMESTAMP
答案 2 :(得分:27)
从2015年12月2日标记的Laravel 5.1.26开始,添加了useCurrent()
修饰符:
Schema::table('users', function ($table) {
$table->timestamp('created')->useCurrent();
});
PR 10962(后跟commit 15c487fe)导致此次添加。
基本上,MySQL 5.7(默认配置)要求您为时间字段定义默认值或可为空。
答案 3 :(得分:16)
作为将来的Google员工的另一种可能性
我发现在创建记录但从未修改过时,在updated_at列中使用空会更有用。它减小了数据库大小(好了,只有一点),并且有可能一眼就看到它从未被修改过。
截至目前,我使用的是
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();
(在Laravel 7和mysql 8中)。
答案 4 :(得分:8)
改为使用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");
它为我创造了奇迹。
答案 5 :(得分:7)
这不适用于事实:
$table->timestamp('created_at')->default('CURRENT_TIMESTAMP');
它不会删除选择时间戳似乎带来的'default 0',它只会附加自定义默认值。但我们有点需要它没有引号。并非操作数据库的所有内容都来自Laravel4。这是他的观点。他希望在某些列上使用自定义默认值,例如:
$table->timestamps()->default('CURRENT_TIMESTAMP');
我认为Laravel不可能。我一直在寻找一小时,看看是否可能。
更新:Paulos Freita的answer表明这是可能的,但语法并不简单。
答案 6 :(得分:1)
我在laravel 5.X的用户表created_at上使用了它,以在创建记录时自动设置时间戳。 (我们有一个客户希望直接在数据库中输入用户,因此我必须确保设置了时间戳记)
<?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());
答案 7 :(得分:1)
我在 Laravel 中使用以下自定义:
首先,我将在 Laravel 的根目录中创建一个文件 helpers.php
并插入以下内容:
<?php
if (!function_exists('database_driver')) {
function database_driver(): string
{
$connection = config('database.default');
return config('database.connections.' . $connection . '.driver');
}
}
if (!function_exists('is_database_driver')) {
function is_database_driver(string $driver): bool
{
return $driver === database_driver();
}
}
在 composer.json 中,我会将以下内容插入到 autoload
中。这允许 Composer 自动发现 helpers.php。
"autoload": {
"files": [
"app/Services/Uploads/Processors/processor_functions.php",
"app/helpers.php"
]
},
我在 Laravel 模型中使用以下内容。
if (is_database_driver('sqlite')) {
$table->timestamps();
} else {
$table->timestamp('created_at')->default(\DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')
->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
}
这允许我的团队继续使用 sqlite 进行单元测试。 ON UPDATE CURRENT_TIMESTAMP
是 MySQL 的快捷方式,在 sqlite 中不可用。
答案 8 :(得分:0)
这就是你如何做到的,我已经检查了它并且它适用于我的Laravel 4.2。
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
希望这有帮助。
答案 9 :(得分:0)
In Laravel 5 simply:
$table->timestamps(); //Adds created_at and updated_at columns.
Documentation: http://laravel.com/docs/5.1/migrations#creating-columns
答案 10 :(得分:0)
使用以下内容:
$table->timestamp('created_at')->nullable();
希望它会对你有所帮助。谢谢。
答案 11 :(得分:0)
如果您要为dateTime列设置当前日期时间(就像我在Google上搜索时一样),请使用这种方式
$table->dateTime('signed_when')->useCurrent();
答案 12 :(得分:0)
在laravel 7中,使用以下命令设置当前时间:
$table->timestamp('column_name')->useCurrent();