Как изменить столбец метки времени?

Я получил файл дампа SQL для существующей базы данных. Существует таблица со столбцами date_from и date_to, они оба имеют отметку времени, но столбец date_to имеет значение по умолчанию 0000-00-00 00:00:00. и при попытке добавить softdeletes в эту таблицу следующим образом:

Schema::table('gamesessions', function (Blueprint $table) {
        $table->softDeletes();
});

я получил следующую ошибку: Неверный формат даты и времени: 1292 Неверное значение даты и времени: «0000-00-00 00:00:00» для столбца ..date_to

поэтому я попытался сделать столбец date_to обнуляемым следующим образом:

Schema::table('gamesessions', function (Blueprint $table) {
        $table->timestamp('date_to')->nullable()->change();
        $table->softDeletes();
});

но, согласно документам laravel, столбец временной метки не подлежит изменению: https://laravel.com/docs/7.x/migrations#modifying-columns

Что бы вы сделали в такой ситуации? заранее спасибо


person Omar    schedule 24.11.2020    source источник


Ответы (2)


Я думаю, вам следует прочитать о DATETIME и TIMESTAMP:

Оба типа данных хранят данные в формате «ГГГГ-ММ-ДД ЧЧ:ММ:СС» и включают дату и время. Несмотря на это сходство, они имеют следующие отличия:

Диапазон — тип данных Datetime поддерживает дату вместе со временем в диапазоне от 1000-01-01 00:00:00 до 9999-12-31 23:59:59. Но тип данных timestamp поддерживает дату вместе со временем в диапазоне от «1970-01-01 00:00:01» до «2038-01-19 08:44:07».

Размер — Datetime требует 5 байтов вместе с 3 дополнительными байтами для хранения данных в долях секунд. С другой стороны, тип данных timestamp требует 4 байта вместе с 3 дополнительными байтами для хранения данных в долях секунд. Но до MySQL 5.6.4 DateTime требовал 8 байтов вместе с 3 дополнительными байтами для хранения данных в долях секунд.

Преобразование из одного часового пояса в другой — на самом деле в MySQL5+ значение метки времени преобразуется из текущего времени в UTC и наоборот, в то время как дата-время не выполняет никакого преобразования.

Индексирование — индексирование данных с отметками времени может быть выполнено, но данные даты и времени не могут быть проиндексированы.

Кэширование запроса — запросы с типом данных метки времени могут быть кэшированы, но запросы с типом данных даты и времени не могут быть кэшированы.

Таким образом, вы не можете сохранить значение даты и времени: «0000-00-00 00:00:00» для столбца date_to

Метод change() позволяет изменять type and attributes существующих столбцов, не изменяя value.

Попробуйте удалить столбец метки времени и повторно добавить его как столбец метки времени с нулевым значением:

    /**
     * Run the migrations.
     *
     * @return void
     */
public function up()
    {
        Schema::table('gamesessions', function (Blueprint $table) {
            $table->dropColumn('date_to');
        });

        Schema::table('gamesessions', function (Blueprint $table) {
            $table->timestamp('date_to')->nullable();
        });
    }

/**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('gamesessions', function (Blueprint $table) {
            $table->dropColumn('date_to');
        });

        Schema::table('gamesessions', function (Blueprint $table) {
            $table->timestamp('date_to');
        });
    }

Подробнее читайте здесь: В чем разница между типами данных MySQL DATETIME и TIMESTAMP?

person Ngô Minh    schedule 24.11.2020
comment
Ваше решение попытается вставить столбец date_to, который уже существует в таблице. Я пытаюсь сделать его обнуляемым вместо значения по умолчанию 0000-00-00 00:00:00. - person Omar; 24.11.2020
comment
о, мой плохой, я думаю, что вы создаете это, а не меняете, извините! я отредактирую свой ответ - person Ngô Minh; 24.11.2020

Альтернативой тому, что вы пытались сделать, является добавление столбца delete_at вручную, например:

Schema::table('gamesessions', function (Blueprint $table) {
        $table->timestamp('deleted_at')->nullable();
});

и в вашей модели игровой сессии:

class Gamesession extends Model
{
    use SoftDeletes;

     /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}
person Marwane Ezzaze    schedule 24.11.2020
comment
Не сработало, проблема не в том, как я вставляю столбец delete_at, а в том, что миграция проверяет структуру таблицы gamesessions и находит столбец date_to с недопустимым значением даты и времени по умолчанию, вот что блокирует миграцию. - person Omar; 24.11.2020