Изменение миграции Laravel, чтобы сделать столбец обнуляемым

Я создал миграцию с неподписанным user_id. Как я могу отредактировать user_id в новой миграции, чтобы также сделать его nullable()?

Schema::create('throttle', function(Blueprint $table)
{
    $table->increments('id');
    // this needs to also be nullable, how should the next migration be?
    $table->integer('user_id')->unsigned();
}

Ответ 1

Laravel 5 теперь поддерживает изменение столбца.

Пример из официального документа

Schema::table('users', function($table)
{
    $table->string('name', 50)->nullable()->change();
});

источник: http://laravel.com/docs/5.0/schema#changing-columns

Laravel 4 не поддерживает изменение столбца. Вы должны написать сырую команду sql.

  // getting Laravel App Instance
   $app = app();

  // getting laravel main version
   $laravelVer = explode('.',$app::VERSION);

    switch ($laravelVer[0]) {

        case('5') :                
            Schema::table('pro_categories_langs', function(Blueprint $t) {
                $t->string('name', 100)->nullable()->default(null)->change();
            });               
            break;                
        /**
         * it is not L5 !!
         */
        default :                
             DB::statement('ALTER TABLE `pro_categories_langs` MODIFY `name` VARCHAR(100) NULL;');                                  
    }

Ответ 2

Я предполагаю, что вы пытаетесь редактировать столбец, на который уже были добавлены данные, поэтому отбрасывание столбца и добавление снова как столбца с нулевым значением невозможно без потери данных. Мы будем alter существующий столбец.

Однако конструктор схем Laravel не поддерживает изменение столбцов, отличных от переименования столбца. Поэтому вам нужно будет запускать необработанные запросы, например:

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
}

И чтобы убедиться, что вы еще можете отменить свою миграцию, мы также сделаем down().

function down()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

Одно замечание состоит в том, что, поскольку вы конвертируете между обнуляемыми и не обнуляемыми, вам нужно убедиться, что вы очищаете данные до/после миграции. Так сделайте это в своей миграции script в обоих направлениях:

function up()
{
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NULL;');
    DB::statement('UPDATE `throttle` SET `user_id` = NULL WHERE `user_id` = 0;');
}

function down()
{
    DB::statement('UPDATE `throttle` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `throttle` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

Ответ 3

Вот полный ответ для будущего читателя. Обратите внимание, что это возможно только в Laravel 5 +.

Прежде всего вам понадобится пакет doctrine/dbal:

composer require doctrine/dbal

Теперь в вашей миграции вы можете сделать это, чтобы сделать столбец нулевым:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

Вам может быть интересно, как вернуть эту операцию. К сожалению, этот синтаксис не поддерживается:

// Sadly does not work :'(
$table->integer('user_id')->unsigned()->change();

Это правильный синтаксис для возврата миграции:

$table->integer('user_id')->unsigned()->nullable(false)->change();

Или, если хотите, вы можете написать необработанный запрос:

public function down()
{
    /* Make user_id un-nullable */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
}

Надеюсь, вы найдете этот ответ полезным.:)

Ответ 4

Это полная миграция для Laravel 5:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable()->change();
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedInteger('user_id')->nullable(false)->change();
    });
}

Дело в том, что вы можете удалить nullable, передав false в качестве аргумента.

Ответ 5

Если вы столкнулись с изменением столбцов и наткнулись на

'Doctrine\DBAL\Driver\PDOMySql\Driver' not found

затем просто установите

composer require doctrine/dbal

Ответ 6

Добавление к Дмитрию Чеботареву Ответ,

Если вы хотите изменить несколько столбцов за раз, вы можете сделать это, как показано ниже

DB::statement('
     ALTER TABLE `events` 
            MODIFY `event_date` DATE NOT NULL,
            MODIFY `event_start_time` TIME NOT NULL,
            MODIFY `event_end_time` TIME NOT NULL;
');

Ответ 7

Добавляя к Дмитрию Чеботареву ответ, как для Laravel 5 +.

После запроса пакета doctrine/dbal:

composer require doctrine/dbal

Затем вы можете выполнить миграцию с нулевыми столбцами, например:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        // change() tells the Schema builder that we are altering a table
        $table->integer('user_id')->unsigned()->nullable()->change();
    });
}

Чтобы вернуть операцию, выполните:

public function down()
{
    /* turn off foreign key checks for a moment */
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    /* set null values to 0 first */
    DB::statement('UPDATE `users` SET `user_id` = 0 WHERE `user_id` IS NULL;');
    /* alter table */
    DB::statement('ALTER TABLE `users` MODIFY `user_id` INTEGER UNSIGNED NOT NULL;');
    /* finally turn foreign key checks back on */
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');

}

Ответ 8

Попробуйте:

$table->integer('user_id')->unsigned()->nullable();

Ответ 9

Для Laravel 4.2 лучший ответ - Unnawut. Но если вы используете префикс таблицы, то вам нужно немного изменить свой код.

function up()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE '' . $table_prefix . 'throttle' MODIFY 'user_id' INTEGER UNSIGNED NULL;');
}

И чтобы убедиться, что вы все еще можете откатить миграцию, мы также сделаем down().

function down()
{
    $table_prefix = DB::getTablePrefix();
    DB::statement('ALTER TABLE '' . $table_prefix . 'throttle' MODIFY 'user_id' INTEGER UNSIGNED NOT NULL;');
}