How Can I Set the Default Value of a Timestamp Column to the Current Timestamp with Laravel Migrations?

☆樱花仙子☆ 提交于 2019-12-17 05:34:27

问题


I would like to make a timestamp column with a default value of CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP using the Laravel Schema Builder/Migrations. I have gone through the Laravel documentation several times, and I don't see how I can make that the default for a timestamp column.

The timestamps() function makes the defaults 0000-00-00 00:00 for both columns that it makes.


回答1:


Given it's a raw expression, you should use DB::raw() to set CURRENT_TIMESTAMP as a default value for a column:

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

This works flawlessly on every database driver.

New shortcut

As of Laravel 5.1.25 (see PR 10962 and commit 15c487fe) you can use the new useCurrent() column modifier method to set the CURRENT_TIMESTAMP as a default value for a column:

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

Back to the question, on MySQL you could also use the ON UPDATE clause through DB::raw():

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

Gotchas

  • MySQL

    Starting with MySQL 5.7, 0000-00-00 00:00:00 is no longer considered a valid date. As documented at the Laravel 5.2 upgrade guide, all timestamp columns should receive a valid default value when you insert records into your database. You may use the useCurrent() column modifier (from Laravel 5.1.25 and above) in your migrations to default the timestamp columns to the current timestamps, or you may make the timestamps nullable() to allow null values.

  • PostgreSQL & Laravel 4.x

    In Laravel 4.x versions, the PostgreSQL driver was using the default database precision to store timestamp values. When using the CURRENT_TIMESTAMP function on a column with a default precision, PostgreSQL generates a timestamp with the higher precision available, thus generating a timestamp with a fractional second part - see this SQL fiddle.

    This will led Carbon to fail parsing a timestamp since it won't be expecting microseconds being stored. To avoid this unexpected behavior breaking your application you have to explicitly give a zero precision to the CURRENT_TIMESTAMP function as below:

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

    Since Laravel 5.0, timestamp() columns has been changed to use a default precision of zero which avoids this.

    Thanks to @andrewhl for pointing out this issue in the comments.




回答2:


To create both of the created_at and updated_at columns:

$t->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$t->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));

You will need MySQL version >= 5.6.5 to have multiple columns with CURRENT_TIMESTAMP




回答3:


Starting from Laravel 5.1.26, tagged on 2015-12-02, a useCurrent() modifier has been added:

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

PR 10962 (followed by commit 15c487fe) leaded to this addition.

You may also want to read issues 3602 and 11518 which are of interest.

Basically, MySQL 5.7 (with default config) requires you to define either a default value or nullable for time fields.




回答4:


This doesn't work for a fact:

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

It doesn't remove the 'default 0' that seems to come with selecting timestamp and it just appends the custom default. But we kind of need it without the quotes. Not everything that manipulates a DB is coming from Laravel4. That's his point. He wants custom defaults on certain columns like:

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

I don't think it's possible with Laravel. I've been searching for an hour now to see whether it's possible.


Update: Paulos Freita's answer shows that it is possible, but the syntax isn't straightforward.




回答5:


Use Paulo Freitas suggestion instead.


Until Laravel fixes this, you can run a standard database query after the Schema::create have been run.

    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");

It worked wonders for me.




回答6:


I used this for laravel 5.X, on the users table created_at to set the timestamps automatically on record creation. (we have a client that wants to input users directly in the DB so I had to make sure the timestamps got set)

<?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();
        });
    }
}

Use that line if you are doing a change migration.

If you are a fan of Carbon, this works great!

Or if you are setting this in your table creation migration.

 $table->dateTime('created_at')->default(\Carbon\Carbon::now());



回答7:


This is how you do it, I have checked it and it works on my Laravel 4.2.

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

Hope this helps.




回答8:


In Laravel 5 simply:

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

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



来源:https://stackoverflow.com/questions/18067614/how-can-i-set-the-default-value-of-a-timestamp-column-to-the-current-timestamp-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!