Laravel迁移表字段类型更改

76

以下是我的文件2015_09_14_051851_create_orders_table.php。 我想在新的迁移中将$table->integer('category_id');更改为字符串。

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateOrdersTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('orders', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('num');
            $table->integer('user_id');

            $table->text('store_name');
            $table->integer('store_name_publication');

            $table->string('postal_code', 255);
            $table->string('phone_number', 255);

            $table->text('title');
            $table->text('description');

            $table->string('list_image_filename1', 255);
            $table->string('list_image_filename2', 255)->nullable();
            $table->string('list_image_filename3', 255)->nullable();
            $table->string('list_image_filename4', 255)->nullable();
            $table->string('list_image_filename5', 255)->nullable();

            $table->integer('term');

            $table->datetime('state0_at')->nullable();
            $table->datetime('state1_at')->nullable();
            $table->datetime('state2_at')->nullable();
            $table->datetime('state3_at')->nullable();
            $table->datetime('state4_at')->nullable();
            $table->datetime('state5_at')->nullable();
            $table->datetime('state6_at')->nullable();
            $table->datetime('state7_at')->nullable();
            $table->datetime('state8_at')->nullable();
            $table->datetime('state9_at')->nullable();
            $table->datetime('state10_at')->nullable();

            $table->integer('category_id');
            $table->integer('target_customer_sex');
            $table->integer('target_customer_age');

            $table->integer('payment_order');
            $table->integer('num_comment');
            $table->integer('num_view');
            $table->string('num_pop');

            $table->integer('money');
            $table->integer('point');

            $table->datetime('closed_at');
            $table->timestamps();
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('orders');
    }

}

$table->string('category_id'); - aldrin27
请仅使用其他迁移文件更改类型,不要修改此类型。 2015_10_05_021049更改类别ID到订单表 - naing linhtut
7个回答

121
更新:2023年10月31日,仍可在laravel 10.x上使用https://laravel.com/docs/10.x/migrations#modifying-columns 要对现有数据库进行一些更改,您可以在迁移中使用change()来修改列类型。
这是您可以做的事情。
Schema::table('orders', function ($table) {
    $table->string('category_id')->change();
});

请注意,您需要将doctrine/dbal依赖项添加到composer.json中。
composer require doctrine/dbal

更多信息可以在这里找到:https://laravel.com/docs/10.x/migrations#modifying-columns

1
现在我正在使用 Laravel 4.2。 - naing linhtut
对于任何想知道的人来说,这个答案已经有几年了,但在Laravel 5.5中仍然可用。 - Bert H
是的。您可以从这里查看 修改列(Laravel 5.5)。 - mininoz
我该如何将字符串转换为整数并添加默认值?我尝试了这个方法,但是PostgreSQL抛出了类型转换错误。 $table->integer('score')->default(0)->change(); - bhattraideb

48
标准解决方案对我不起作用,当我将类型从TEXT更改为LONGTEXT时。
我必须这样做:
public function up()
{
    DB::statement('ALTER TABLE mytable MODIFY mycolumn  LONGTEXT;');
}

public function down()
{
    DB::statement('ALTER TABLE mytable MODIFY mycolumn TEXT;');
}

可能是Doctrine的问题。更多信息在这里

另一种方法是使用string()方法,并将值设置为文本类型的最大长度:

    Schema::table('mytable', function ($table) {
        // Will set the type to LONGTEXT.
        $table->string('mycolumn', 4294967295)->change();
    });

2
这对于DECIMAL列非常有用。 - dmmd
2
我可以确认这种行为。为了将列从文本更改为mediumtext,我必须执行以下操作:$table->string('messages', 16777215)->nullable()->change(); - Antonio
1
$table->longText('mycolumn')->change(); - Rockin4Life33
这是一个很好的解决方案,因为Laravel迁移不支持在同一张表中存在另一个ENUM字段时更改任何其他字段类型。 - Thiago Elias
但它无法运行测试。 - Ray Coder

12

2018年的解决方案,还有其他有效的答案,但您不需要使用任何依赖项

首先,您必须创建一个新的迁移:

php artisan make:migration change_appointment_time_column_type

然后在那个迁移文件的up()方法中,尝试:

    Schema::table('appointments', function ($table) {
        $table->string('time')->change();
    });
如果您不更改大小,那么默认值将为varchar(191),但如果您想更改字段的大小:
    Schema::table('appointments', function ($table) {
        $table->string('time', 40)->change();
    });

然后按照以下步骤迁移文件:

php artisan migrate

文档中有更多信息


2
你还需要使用“doctrine/dbal”依赖吗? - Abhay Maurya
1
在我看来,这是唯一正确的答案。由于迁移文件除了改变模式之外,还是文档编写和版本控制数据库模式更改的手段,因此在这里必须使用单独的迁移文件。 - Valentine Shi
4
你仍需要使用 doctrine/dbal - Theodore R. Smith
需要 doctrine/dbal 包。 - golchha21

10

所有其他答案都是正确的但是在运行之前,请注意

php artisan migrate

确保你首先运行此代码

composer require doctrine/dbal

为避免这个错误

RuntimeException:更改"items"表的列需要Doctrine DBAL;请安装"doctrine/dbal"。


8

首先需要安装 doctrine/dbal,然后:

$table->longText('column_name')->change();

1

并不是一个答案,只是关于 ->change() 的一些说明:

只有以下列类型可以被“更改”:bigInteger、binary、boolean、date、dateTime、dateTimeTz、decimal、integer、json、longText、mediumText、smallInteger、string、text、time、unsignedBigInteger、unsignedInteger 和 unsignedSmallInteger。

https://laravel.com/docs/5.8/migrations#modifying-columns

如果您的列不属于这些列之一,则需要删除该列或使用其他答案中提到的 alter 语句。


0
对我来说,解决方案就是将unsigned替换为index 这是完整的代码:
    Schema::create('champions_overview',function (Blueprint $table){
        $table->engine = 'InnoDB';
        $table->increments('id');
        $table->integer('cid')->index();
        $table->longText('name');
    });


    Schema::create('champions_stats',function (Blueprint $table){
        $table->engine = 'InnoDB';
        $table->increments('id');
        $table->integer('championd_id')->index();
        $table->foreign('championd_id', 'ch_id')->references('cid')->on('champions_overview');
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接