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

Мне нужно изменить два поля от целого до внешнего ключа. Как мне настроить миграцию для этого?

Schema::create('messages', function($table)
{
    $table->increments('id');
    $table->integer('sender');
    $table->integer('recipient');
    $table->string('title');
    $table->longtext('body');
    $table->timestamps();
    $table->softDeletes();
    $table->integer('regarding');
});

Я изменю sender на sender_id, recipient на recipient_id и regarding на regarding_id.

Ответ 1

Я столкнулся с аналогичной проблемой, требующей изменить тип столбца от строки до целого. Я справился с этим, используя две отдельные миграции (с каждой командой RAW sql) для получения решения.

Кроме того, это работает с Postgres и MySQL, потому что мы находились в середине передачи.

Первая миграция:

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    Schema::table('plans', function(Blueprint $table)
    {
        //
        $table->mediumInteger('duration_change_type')->default(0)->after('duration');
    });

    if (Config::get('database')['default'] === 'mysql'){
        // Mysql 
        DB::statement('update plans set duration_change_type=duration');

    } else if (Config::get('database')['default'] === 'pgsql'){
        // PostgreSQL
        DB::statement('update plans set duration_change_type=duration::integer');
    }
}

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

Вторая миграция:

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

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    Schema::table('plans', function(Blueprint $table)
    {
        // Rollback to string
        $table->string('duration_change_type')->default(0)->after('duration');
    });
    if (Config::get('database')['default'] === 'mysql'){
        // Mysql 
        DB::statement('update plans set duration_change_type=duration');

    } else if (Config::get('database')['default'] === 'pgsql'){
        // PostgreSQL
        DB::statement('update plans set duration_change_type=duration::text');
    }
}

Мысль об этом теперь может быть упрощена до одной миграции.

Ответ 2

Не думай об этом слишком много, я использую следующий код. Здесь я меняю тип данных с varchar на текст.

public function up(){
    DB::statement('ALTER TABLE items MODIFY COLUMN item_description TEXT');
    DB::statement('ALTER TABLE items MODIFY COLUMN delivery_description TEXT');
}

public function down(){
    DB::statement('ALTER TABLE items MODIFY COLUMN item_description VARCHAR(255)');
    DB::statement('ALTER TABLE items MODIFY COLUMN delivery_description VARCHAR(255)');
} 

Ответ 3

Я только что столкнулся с одной проблемой, и самым быстрым решением является просто изменить структуру столбцов в базе данных, а затем изменить первоначальную миграцию, чтобы отразить изменения, сделанные в БД.

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

Ответ 4

Если вы хотите изменить тип столбца или длину изменения и т.д., просто вызовите метод change()

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

и переименовать столбец

Schema::table('users', function ($table) {
    $table->renameColumn('from', 'to');
});

Ответ 5

Вы можете попробовать переименовать столбец во временное с $table->renameColumn('from', 'to');, затем создать новый столбец со стандартной строкой создания для внешнего ключа и, наконец, скопировать данные из временного столбца в новый с помощью функции контроллера. Должен работать, но я не пробовал, не нуждался.

Ответ 6

Я бы просто отбросил его, а затем снова добавил его как другой тип.

Ответ 7

В Laravel 5 вы можете использовать закрытие, например, ниже. Это должно сделать это в агностическом режиме базы данных, поэтому не нужно иметь if-statements, проверяющий типы баз данных.

(Обратите внимание, что для этого вам может потребоваться композитор, для которого требуется доктрина /dbal .)

public function up() {
    Schema::table('plans', function($t) {
        $t->renameColumn('duration_change_type', 'duration');
    });
}

public function down() {
    Schema::table('plans', function($t) {
        $t->renameColumn('duration', 'duration_change_type');
    });
}

Ответ 8

У меня была аналогичная проблема, пытающаяся изменить тип столбца из текста в двоичный. При попытке запустить команду migrate я получал сообщение об ошибке. В итоге я решил это так:

public function up()
{
    Schema::table('user', function (Blueprint $table) {
        $table->dropColumn('address');
    });
    Schema::table('user', function (Blueprint $table) {
        $table->binary('address')->nullable();
    });
}