2017-03-08 66 views
3

我得到一個錯誤,當我嘗試從字符串到文本的列類型時,使用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://stackoverflow.com/questions/1827063/mysql-error-key-specification-without-a-key-length –

回答

2

您需要分三步執行此操作,或者使用三次單獨的遷移,或者三次調用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

0

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