web-dev-qa-db-ja.com

Laravel Migrationsでタイムスタンプ列のデフォルト値を現在のタイムスタンプに設定する方法はありますか

Laravel Schema Builder/Migrationsを使用して、デフォルト値CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPでタイムスタンプ列を作成したいと思います。私はLaravelのドキュメントを何度か調べましたが、それをタイムスタンプ列のデフォルトにする方法がわかりません。

timestamps()関数は、作成する両方の列に対してデフォルトの0000-00-00 00:00を作成します。

123
JoeyD473

生の式だとすると、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では、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は有効な日付とは見なされなくなりました。 Laravel 5.2 upgrade guide に記載されているように、データベースにレコードを挿入すると、すべてのタイムスタンプ列に有効なデフォルト値が設定されます。移行でuseCurrent()列修飾子(Laravel 5.1.25以降)を使用して、タイムスタンプ列を現在のタイムスタンプにデフォルト設定するか、タイムスタンプnullable()を使用してnull値を許可できます。

  • PostgreSQL&Laravel 4.x

    Laravel 4.xバージョンでは、PostgreSQLドライバーはデフォルトのデータベース精度を使用してタイムスタンプ値を保存していました。デフォルトの精度の列でCURRENT_TIMESTAMP関数を使用する場合、PostgreSQLはより高い精度のタイムスタンプを生成し、秒の小数部を含むタイムスタンプを生成します- このSQL fiddleを参照

    これにより、Carbonはマイクロ秒が保存されることを期待しないため、タイムスタンプの解析に失敗します。アプリケーションを壊すこの予期しない動作を回避するには、次のようにCURRENT_TIMESTAMP関数に明示的にゼロ精度を与える必要があります。

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

    Laravel 5.0以降、timestamp()列は、これを回避するデフォルトの精度ゼロを使用するように変更されました。

    コメントでこの問題を指摘してくれた @ andrewhl に感謝します。

229
Paulo Freitas

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

CURRENT_TIMESTAMPを使用して複数の列を作成するには、MySQLバージョン5.6.5以上が必要です。

43
Brian Adams

2015年12月2日にタグ付けされたLaravel 5.1.26以降、useCurrent()修飾子が追加されました。

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

PR 10962 (続いて commit 15c487fe )がこの追加につながりました。

また、興味のある問題 602 および 11518 を読むこともできます。

基本的に、MySQL 5.7(デフォルトの構成)では、デフォルト値を定義するか、時間フィールドにNULL値を許可する必要があります。

28
Gras Double

Paulo Freitasを使用してください 提案 代わりに。


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

それは私にとって不思議でした。

7
Marwelln

これは実際には機能しません:

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

タイムスタンプの選択に伴うと思われる「デフォルト0」は削除されず、カスタムのデフォルトが追加されるだけです。しかし、引用符なしでそれを必要としています。 DBを操作するすべてがLaravel4から来るわけではありません。それが彼のポイントです。彼は、次のような特定の列のカスタムデフォルトを望んでいます。

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

Laravelでそれが可能になるとは思わない。可能かどうかを確認するために、今から1時間探しています。


更新:Paulos Freitaの answer は可能であることを示していますが、構文は簡単ではありません。

7
Glenn Plas

Usersテーブル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());
2
dustbuster

次を使用します。

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

うまくいけば、それがあなたを助けるでしょう。ありがとうございました。

0
Foysal Nibir

これがあなたのやり方です、私はそれをチェックしました、そしてそれは私のLaravel 4.2で動作します。

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

お役に立てれば。

0
Jawad

Laravel 5の場合:

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

ドキュメント: http://laravel.com/docs/5.1/migrations#creating-columns

0
JoenMarz