如何迁移更改列类型?

如何迁移更改列类型?

问题描述:

我得到一个错误,当我尝试从字符串到文本的列类型时,使用Laravel的迁移函数。如何迁移更改列类型?

文件:{} data_time _change_db_structure.php

public function up() 
    { 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->dropIndex(['sro_key_group']); 

     $table->text('sro_key_group')->change(); 
     $table->renameColumn('sro_key_group', 'tags'); 
    }); 
    } 

这是原单迁移创建表文件。

public function up() 
    { 
    Schema::create('service_request_type', function (Blueprint $table) { 
     $table->engine = 'InnoDB'; 
     ... 
     $table->string('sro_key_group', 100)->nullable()->index(); 
     ... 
    }); 
    } 

我得到了错误。

[照亮\数据库\ QueryException]
SQLSTATE [42000]:语法错误或访问冲突:1170 BLOB/TEXT 列在密钥规范没有一个密钥长度 'sro_key_group'(SQL:ALTER TABLE service_request_type CHANGE sro_key_group SRO _key_group TEXT DEFAULT NULL COLLATE utf8_unicode_ci)

                                  [Doctrine\DBAL\Driver\PDOException]         

SQLSTATE [42000]:语法错误或访问冲突:1170 BLOB/TEXT 列中的密钥规范使用而不 'sro_key_group'密钥长度

                                  [PDOException]               

SQLSTATE [42000]:语法错误或访问冲突:1170 BLOB/TEXT 列在密钥规范没有一个密钥长度

什么错误 'sro_key_group'?我已经在我的composer.json中安装doctrine/dbal

+0

sro_key_group是否存在多个索引? – patricus

+0

@patricus'sro_key_group'不是多个索引 – ThunderBirdsX3

+0

@ ThunderBirdsX3请参阅http://*.com/questions/1827063/mysql-error-key-specification-without-a-key-length –

您需要分三步执行此操作,或者使用三次单独的迁移,或者三次调用table(),正如您在答案中所示。

第一个问题是,即使您已按照您希望它们执行的顺序(以及它们需要执行的顺序)编写语句,模式构建器实际上会重新排列顺序,以便“更改“语句首先执行。模式构建器将新列和更改列视为“隐含”语句,并将它们移动到要运行的命令堆栈的顶部。但是,重命名语句不被视为“更改”语句。

所以,即使你写的代码:

[ 
    remove index, 
    change column from varchar to text, 
    rename column, 
] 

架构生成器将实际执行:现在

[ 
    change column from varchar to text, 
    remove index, 
    rename column, 
] 

,因为被删除的列前的变化命令正在发生从索引,你得到1170错误。

下一个问题是尝试在相同的上下文中进行列更改和列重命名。通过执行模式差异来生成实现请求更改的SQL,但是在实际进行任何更改之前,两个模式差异都将完成。因此,从varchartext的第一个更改将生成适当的SQL以进行更改,但是第二次更改重命名该列实际上会生成SQL,将列返回更改为文本字段,同时对其进行重命名。

要解决这些问题,您可以创建三个迁移,第一个迁移只需删除索引,第二个迁移更改类型,然后第三个迁移将其重命名,或者可以保留一个迁移并运行三个table()陈述。

public function up() 
{ 
    // make sure the index is dropped first 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->dropIndex(['sro_key_group']); 
    }); 

    // now change the type of the field 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->text('sro_key_group')->nullable()->change(); 
    }); 

    // now rename the field 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->renameColumn('sro_key_group', 'tags'); 
    }); 
} 
+0

太好了!非常感谢你。 – ThunderBirdsX3

+0

嗯,看起来'sro_key_group'不会在你的答案中变为'text',但在我的答案中它工作。 – ThunderBirdsX3

+0

@ ThunderBirdsX3我已经更新了我的答案,并提供了更多有关为何发生这种情况的信息。 – patricus

Ahhhhhh mannnnn ...

我得到了答案。

public function up() 
    { 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->dropIndex(['sro_key_group']); 
    }); 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->text('sro_key_group')->nullable()->change(); 
    }); 
    Schema::table('service_request_type', function (Blueprint $table) { 
     $table->renameColumn('sro_key_group', 'tags'); 
    }); 
    } 

Hmmmmmmm跆拳道是什么?

+0

我知道这是怎么回事。我会写一个答案。 – patricus

+0

我发布了一个答案,让你知道为什么你有这个问题。 – patricus