2014-02-27 53 views
11

我需要将整数更改为外键的两个字段。我如何构建我的迁移来执行此操作?如何使用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'); 
}); 

我会改变sendersender_idrecipientrecipient_idregardingregarding_id

回答

0

您可以尝试将列重命名为$table->renameColumn('from', 'to');,然后使用标准外键创建新列,最后将数据从临时列复制到具有控制器功能的新列。 应该工作,但我没有尝试,没有需要。

+0

我已经完成了上述工作,它可以同时工作:)。 – Ben

7

我遇到了类似的问题,需要将列类型从字符串更改为整数。我使用两个单独的迁移(每个都使用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'); 
    } 
} 

在此思考现在它可以被简化成一个单一的迁移。

+1

谢谢,本。我会修补那个。 – mike

3

我刚刚遇到同样的问题,最快的解决方案是简单地更改数据库上的列结构,然后改变原始迁移以反映对数据库所做的更改。

通过这种方式,如果迁移曾经回滚,然后再次上升,正确的字段将被创建。只要您确保准确更改迁移,我就看不到任何不利之处。

+3

如果您只部署到一台服务器,那没问题,但是如果您部署到10台服务器,您是否会逐个更改该列? –

7

不要想太多,我使用下面的代码。在这里,我将数据类型从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)'); 
} 
+0

这不适用于Postgres,你必须使用这个: DB :: statement('ALTER TABLE items ALTER COLUMN item_description TYPE VARCHAR(20)'); – hdomos

2

如果要更改列类型或修改长度等,只需调用change()方法

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

和重命名列

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

我只想砸和然后将其重新添加为不同的类型。

0

在Laravel 5中,您可以使用如下的闭包。这应该以与数据库无关的方式执行,因此不需要使用if语句来检查数据库类型。

(请注意,您可能需要作曲家需要学说/ 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'); 
    }); 
} 
0

我有一个类似的问题,试图列类型更改从文本到二进制文件。尝试运行迁移命令时出现错误。 我最终以这种方式解决了这个问题:

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