Eu criei uma tabela usando a migração como esta:
public function up()
{
Schema::create('despatch_discrepancies', function($table) {
$table->increments('id')->unsigned();
$table->integer('pick_id')->unsigned();
$table->foreign('pick_id')->references('id')->on('picks');
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->integer('original_qty')->unsigned();
$table->integer('shipped_qty')->unsigned();
});
}
public function down()
{
Schema::drop('despatch_discrepancies');
}
Eu preciso mudar esta tabela e descartar a referência de chave estrangeira e coluna pick_detail_id
e adicionar uma nova coluna varchar chamada sku
após pick_id
coluna.
Então, criei outra migração, que se parece com isto:
public function up()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->dropForeign('pick_detail_id');
$table->dropColumn('pick_detail_id');
$table->string('sku', 20)->after('pick_id');
});
}
public function down()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->dropColumn('sku');
});
}
Quando executo essa migração, recebo o seguinte erro:
[Illuminate \ Database \ QueryException]
SQLSTATE [HY000]: Erro geral: 1025 Erro na renomeação de './dev_iwms_reboot/despatch_discrepancies' para './dev_iwms_reboot/#sql2-67c-17c464' (errno: 152) (tabela SQL: alterdespatch_discrepancies
largar chave estrangeira pick_detail_id)[PDOException]
SQLSTATE [HY000]: Erro geral: 1025 Erro na renomeação de './dev_iwms_reboot/despatch_discrepancies' para './dev_iwms_reboot/#sql2-67c-17c464' (errno: 152)
Quando tento reverter essa migração executando o php artisan migrate:rollback
comando, recebo uma Rolled back
mensagem, mas na verdade não está fazendo nada no banco de dados.
Alguma ideia do que pode estar errado? Como você elimina uma coluna que tem uma referência de chave estrangeira?
fonte
Acontece que; quando você cria uma chave estrangeira como esta:
$table->integer('pick_detail_id')->unsigned(); $table->foreign('pick_detail_id')->references('id')->on('pick_details');
O Laravel nomeia exclusivamente a referência de chave estrangeira assim:
<table_name>_<foreign_table_name>_<column_name>_foreign despatch_discrepancies_pick_detail_id_foreign (in my case)
Portanto, quando você deseja eliminar uma coluna com referência de chave estrangeira, você deve fazer desta forma:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign'); $table->dropColumn('pick_detail_id');
Atualizar:
Laravel 4.2+ introduz uma nova convenção de nomenclatura:
fonte
<table_name>_<column_name>_foreign
convenção ainda parece funcionar para 5.1$table->dropIndex('column_name')
.Eu tinha várias chaves estrangeiras em minha tabela e, em seguida, tive que remover as restrições de chave estrangeira, uma por uma, passando o nome da coluna como índice do array no método down:
public function up() { Schema::table('offices', function (Blueprint $table) { $table->unsignedInteger('country_id')->nullable(); $table->foreign('country_id') ->references('id') ->on('countries') ->onDelete('cascade'); $table->unsignedInteger('stateprovince_id')->nullable(); $table->foreign('stateprovince_id') ->references('id') ->on('stateprovince') ->onDelete('cascade'); $table->unsignedInteger('city_id')->nullable(); $table->foreign('city_id') ->references('id') ->on('cities') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('offices', function (Blueprint $table) { $table->dropForeign(['country_id']); $table->dropForeign(['stateprovince_id']); $table->dropForeign(['city_id']); $table->dropColumn(['country_id','stateprovince_id','city_id']); }); }
Usar a declaração abaixo não funciona
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Porque dropForeign não os considera colunas separadas que queremos remover. Portanto, temos que soltá-los um por um.
fonte
$table->dropIndex('column_name')
.A chave (para mim) para resolver isso era ter certeza de que o comando $ table-> dropForeign () estava recebendo o nome de relacionamento correto, não necessariamente o nome da coluna. Você não quer passar o nome da coluna, pois seria muito mais intuitivo IMHO.
O que funcionou para mim foi:
$table->dropForeign('local_table_foreign_id_foreign'); $table->column('foreign_id');
Portanto, a string que passei para dropForeign () que funcionou para mim estava no formato de:
[tabela local] _ [campo de chave estrangeira] _foreign
Se você tiver acesso a uma ferramenta como Sequel Pro ou Navicat, poder visualizá-las será muito útil.
fonte
Algo que me ocorreu foi que eu não sabia onde colocar o
Schema::table
bloqueio.Mais tarde descobri que a chave está no erro SQL:
[Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table if exists `lu_benefits_categories`)
Então o
Schema::table
bloco precisa ir nadown()
função dalu_benefits_categories
migração e antes daSchema::dropIfExists
linha:public function down() { Schema::table('table', function (Blueprint $table) { $table->dropForeign('table_category_id_foreign'); $table->dropColumn('category_id'); }); Schema::dropIfExists('lu_benefits_categories'); }
Depois disso, o
php artisan migrate:refresh
ouphp artisan migrate:reset
fará o truque.fonte