Как я могу установить значение по умолчанию столбца метки времени на текущую метку времени с миграциями Laravel?

Я хотел бы создать столбец отметки времени со значением по умолчанию CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP с использованием Laravel Schema Builder/Migrations. Я несколько раз просматривал документацию по Laravel и не понимаю, как сделать это по умолчанию для столбца метки времени.

Функция timestamps() делает значения по умолчанию 0000-00-00 00:00 для обоих столбцов, которые она делает.

Ответ 1

Учитывая это необработанное выражение, вы должны использовать 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'));

Gotchas

  • MySQL

    Начиная с MySQL 5.7, 0000-00-00 00:00:00 больше не считается действительной датой. Как описано в руководстве по обновлению Laravel 5.2, все столбцы меток времени должны получать действительное значение по умолчанию при вставке записей в базу данных. Вы можете использовать модификатор столбца useCurrent() (начиная с Laravel 5.1.25 и выше) в своих миграциях, чтобы по умолчанию использовать столбцы меток времени с текущими метками времени, или вы можете сделать метки времени nullable() чтобы разрешить нулевые значения.

  • PostgreSQL и Laravel 4.x

    В версиях Laravel 4.x драйвер PostgreSQL использовал точность базы данных по умолчанию для хранения значений меток времени. При использовании функции CURRENT_TIMESTAMP для столбца с точностью по умолчанию PostgreSQL генерирует временную метку с более высокой доступной точностью, таким образом генерируя временную метку с дробной второй частью - см. Эту скрипту SQL.

    Это приведет к тому, что Carbon потерпит неудачную обработку метки времени, поскольку он не будет ожидать сохранения микросекунд. Чтобы избежать этого неожиданного поведения, нарушающего работу вашего приложения, вы должны явно дать нулевую точность функции CURRENT_TIMESTAMP как CURRENT_TIMESTAMP ниже:

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

    Начиная с Laravel 5.0, столбцы timestamp() были изменены для использования точности по умолчанию, равной нулю, что позволяет избежать этого.

    Спасибо @andrewhl за указание на эту проблему в комментариях.

Ответ 2

Чтобы создать оба столбца 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 version >= 5.6.5, чтобы иметь несколько столбцов с CURRENT_TIMESTAMP

Ответ 3

Начиная с Laravel 5.1.26, помеченного на 2015-12-02, добавлен модификатор useCurrent():

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

PR 10962 (за ним следует commit 15c487fe). к этому добавлению.

Вы также можете прочитать проблемы 3602 и 11518, которые представляют интерес.

В принципе, MySQL 5.7 (с конфигурацией по умолчанию) требует, чтобы вы определяли либо значение по умолчанию, либо значение NULL для полей времени.

Ответ 4

Это не работает для факта:

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

Он не удаляет "default 0", который, кажется, подходит для выбора отметки времени, и он просто добавляет пользовательский по умолчанию. Но мы нуждаемся в этом без кавычек. Не все, что манипулирует БД, происходит от Laravel4. Это его точка. Он хочет использовать стандартные значения по умолчанию для определенных столбцов, например:

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

Я не думаю, что это возможно с Ларавелем. Я искал час, чтобы увидеть, возможно ли это.


Обновление: Paulos Freita answer показывает, что это возможно, но синтаксис не является простым.

Ответ 5

Вместо этого используйте 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");

Это сработало для меня чудеса.

Ответ 6

Я использовал это для laravel 5.X, в таблице пользователей selected_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

Вот как вы это делаете, я проверил его, и он работает на моем Laravel 4.2.

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

Надеюсь, что это поможет.

Ответ 9

Используйте следующее:

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

Надеюсь, это поможет вам. Спасибо.

Ответ 10

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